diff --git a/.gitignore b/.gitignore index cf04fcae..4e0dff02 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ node_modules coverage docs tests/build +typechain +!src/typechain .idea .vscode diff --git a/abi/IBridgehub.json b/abi/IBridgehub.json new file mode 100644 index 00000000..22db2fd4 --- /dev/null +++ b/abi/IBridgehub.json @@ -0,0 +1,631 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "stateTransitionManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "chainGovernance", + "type": "address" + } + ], + "name": "NewChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPendingAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event" + }, + { + "inputs": [], + "name": "acceptAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stateTransitionManager", + "type": "address" + } + ], + "name": "addStateTransitionManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "addToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "baseToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_stateTransitionManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_baseToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_initData", + "type": "bytes" + } + ], + "name": "createNewChain", + "outputs": [ + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "getStateTransition", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_gasPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2GasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2GasPerPubdataByteLimit", + "type": "uint256" + } + ], + "name": "l2TransactionBaseCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + }, + { + "internalType": "enum TxStatus", + "name": "_status", + "type": "uint8" + } + ], + "name": "proveL1ToL2TransactionStatus", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_batchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint8", + "name": "l2ShardId", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "isService", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "txNumberInBatch", + "type": "uint16" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "value", + "type": "bytes32" + } + ], + "internalType": "struct L2Log", + "name": "_log", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "_proof", + "type": "bytes32[]" + } + ], + "name": "proveL2LogInclusion", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_batchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint16", + "name": "txNumberInBatch", + "type": "uint16" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct L2Message", + "name": "_message", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "_proof", + "type": "bytes32[]" + } + ], + "name": "proveL2MessageInclusion", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stateTransitionManager", + "type": "address" + } + ], + "name": "removeStateTransitionManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mintValue", + "type": "uint256" + }, + { + "internalType": "address", + "name": "l2Contract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "l2Value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "l2Calldata", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "l2GasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2GasPerPubdataByteLimit", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "factoryDeps", + "type": "bytes[]" + }, + { + "internalType": "address", + "name": "refundRecipient", + "type": "address" + } + ], + "internalType": "struct L2TransactionRequestDirect", + "name": "_request", + "type": "tuple" + } + ], + "name": "requestL2TransactionDirect", + "outputs": [ + { + "internalType": "bytes32", + "name": "canonicalTxHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mintValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2Value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2GasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2GasPerPubdataByteLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "refundRecipient", + "type": "address" + }, + { + "internalType": "address", + "name": "secondBridgeAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "secondBridgeValue", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "secondBridgeCalldata", + "type": "bytes" + } + ], + "internalType": "struct L2TransactionRequestTwoBridgesOuter", + "name": "_request", + "type": "tuple" + } + ], + "name": "requestL2TransactionTwoBridges", + "outputs": [ + { + "internalType": "bytes32", + "name": "canonicalTxHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newPendingAdmin", + "type": "address" + } + ], + "name": "setPendingAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sharedBridge", + "type": "address" + } + ], + "name": "setSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sharedBridge", + "outputs": [ + { + "internalType": "contract IL1SharedBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "stateTransitionManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stateTransitionManager", + "type": "address" + } + ], + "name": "stateTransitionManagerIsRegistered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_baseToken", + "type": "address" + } + ], + "name": "tokenIsRegistered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/IContractDeployer.json b/abi/IContractDeployer.json index 8f54565c..2525a786 100644 --- a/abi/IContractDeployer.json +++ b/abi/IContractDeployer.json @@ -84,7 +84,7 @@ "outputs": [ { "internalType": "address", - "name": "newAddress", + "name": "", "type": "address" } ], @@ -113,7 +113,7 @@ "outputs": [ { "internalType": "address", - "name": "newAddress", + "name": "", "type": "address" } ], @@ -147,7 +147,7 @@ "outputs": [ { "internalType": "address", - "name": "newAddress", + "name": "", "type": "address" } ], @@ -158,7 +158,7 @@ "inputs": [ { "internalType": "bytes32", - "name": "_salt", + "name": "", "type": "bytes32" }, { @@ -181,10 +181,114 @@ "outputs": [ { "internalType": "address", - "name": "newAddress", + "name": "", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "extendedAccountVersion", + "outputs": [ + { + "internalType": "enum IContractDeployer.AccountAbstractionVersion", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "bytecodeHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "newAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "callConstructor", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "input", + "type": "bytes" + } + ], + "internalType": "struct ContractDeployer.ForceDeployment", + "name": "_deployment", + "type": "tuple" + }, + { + "internalType": "address", + "name": "_sender", "type": "address" } ], + "name": "forceDeployOnAddress", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "bytecodeHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "newAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "callConstructor", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "input", + "type": "bytes" + } + ], + "internalType": "struct ContractDeployer.ForceDeployment[]", + "name": "_deployments", + "type": "tuple[]" + } + ], + "name": "forceDeployOnAddresses", + "outputs": [], "stateMutability": "payable", "type": "function" }, diff --git a/abi/IL1Bridge.json b/abi/IL1Bridge.json index 36bc6b52..7069b2de 100644 --- a/abi/IL1Bridge.json +++ b/abi/IL1Bridge.json @@ -2,6 +2,80 @@ { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "l2DepositTxHash", + "type": "bytes32" + } + ], + "name": "BridgehubDepositFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "BridgehubDepositInitiatedSharedBridge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, { "indexed": true, "internalType": "address", @@ -21,12 +95,18 @@ "type": "uint256" } ], - "name": "ClaimedFailedDeposit", + "name": "ClaimedFailedDepositSharedBridge", "type": "event" }, { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, { "indexed": true, "internalType": "bytes32", @@ -40,7 +120,7 @@ "type": "address" }, { - "indexed": true, + "indexed": false, "internalType": "address", "name": "to", "type": "address" @@ -58,12 +138,18 @@ "type": "uint256" } ], - "name": "DepositInitiated", + "name": "DepositInitiatedSharedBridge", "type": "event" }, { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, { "indexed": true, "internalType": "address", @@ -83,11 +169,136 @@ "type": "uint256" } ], - "name": "WithdrawalFinalized", + "name": "WithdrawalFinalizedSharedBridge", "type": "event" }, + { + "inputs": [], + "name": "bridgehub", + "outputs": [ + { + "internalType": "contract IBridgehub", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_txDataHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_txHash", + "type": "bytes32" + } + ], + "name": "bridgehubConfirmL2Transaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_prevMsgSender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "bridgehubDeposit", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "magicValue", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "l2Contract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "l2Calldata", + "type": "bytes" + }, + { + "internalType": "bytes[]", + "name": "factoryDeps", + "type": "bytes[]" + }, + { + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + } + ], + "internalType": "struct L2TransactionRequestTwoBridgesInner", + "name": "request", + "type": "tuple" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_prevMsgSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "bridgehubDepositBaseToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, { "internalType": "address", "name": "_depositSender", @@ -98,6 +309,11 @@ "name": "_l1Token", "type": "address" }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, { "internalType": "bytes32", "name": "_l2TxHash", @@ -131,6 +347,11 @@ }, { "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, { "internalType": "address", "name": "_l2Receiver", @@ -141,6 +362,11 @@ "name": "_l1Token", "type": "address" }, + { + "internalType": "uint256", + "name": "_mintValue", + "type": "uint256" + }, { "internalType": "uint256", "name": "_amount", @@ -175,6 +401,35 @@ }, { "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + } + ], + "name": "depositHappened", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, { "internalType": "uint256", "name": "_l2BatchNumber", @@ -208,6 +463,11 @@ }, { "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, { "internalType": "uint256", "name": "_l2BatchNumber", @@ -219,7 +479,7 @@ "type": "uint256" } ], - "name": "isWithdrawalFinalized", + "name": "isWithdrawalFinalizedShared", "outputs": [ { "internalType": "bool", @@ -230,28 +490,15 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "l2Bridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { - "internalType": "address", - "name": "_l1Token", - "type": "address" + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" } ], - "name": "l2TokenAddress", + "name": "l2BridgeAddress", "outputs": [ { "internalType": "address", diff --git a/abi/IL1ERC20Bridge.json b/abi/IL1ERC20Bridge.json new file mode 100644 index 00000000..bdade3c8 --- /dev/null +++ b/abi/IL1ERC20Bridge.json @@ -0,0 +1,377 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimedFailedDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "l2DepositTxHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DepositInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawalFinalized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "claimFailedDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l2Receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasPerPubdataByte", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l2Receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasPerPubdataByte", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_refundRecipient", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_depositL2TxHash", + "type": "bytes32" + } + ], + "name": "depositAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "finalizeWithdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + } + ], + "name": "isWithdrawalFinalized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2Bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + } + ], + "name": "l2TokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2TokenBeacon", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sharedBridge", + "outputs": [ + { + "internalType": "contract IL1SharedBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "transferTokenToSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/abi/IL1SharedBridge.json b/abi/IL1SharedBridge.json new file mode 100644 index 00000000..a56f86eb --- /dev/null +++ b/abi/IL1SharedBridge.json @@ -0,0 +1,692 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "BridgehubDepositBaseTokenInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "l2DepositTxHash", + "type": "bytes32" + } + ], + "name": "BridgehubDepositFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "BridgehubDepositInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimedFailedDepositSharedBridge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "l2DepositTxHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "LegacyDepositInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawalFinalizedSharedBridge", + "type": "event" + }, + { + "inputs": [], + "name": "bridgehub", + "outputs": [ + { + "internalType": "contract IBridgehub", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_txDataHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_txHash", + "type": "bytes32" + } + ], + "name": "bridgehubConfirmL2Transaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_prevMsgSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_l2Value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "bridgehubDeposit", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "magicValue", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "l2Contract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "l2Calldata", + "type": "bytes" + }, + { + "internalType": "bytes[]", + "name": "factoryDeps", + "type": "bytes[]" + }, + { + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + } + ], + "internalType": "struct L2TransactionRequestTwoBridgesInner", + "name": "request", + "type": "tuple" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_prevMsgSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "bridgehubDepositBaseToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_depositSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "claimFailedDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "claimFailedDepositLegacyErc20Bridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + } + ], + "name": "depositHappened", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_msgSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasPerPubdataByte", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_refundRecipient", + "type": "address" + } + ], + "name": "depositLegacyErc20Bridge", + "outputs": [ + { + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "finalizeWithdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "finalizeWithdrawalLegacyErc20Bridge", + "outputs": [ + { + "internalType": "address", + "name": "l1Receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + } + ], + "name": "isWithdrawalFinalized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1WethAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "l2BridgeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "legacyBridge", + "outputs": [ + { + "internalType": "contract IL1ERC20Bridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "receiveEth", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_eraFirstPostUpgradeBatch", + "type": "uint256" + } + ], + "name": "setEraFirstPostUpgradeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/ITestnetERC20Token.json b/abi/ITestnetERC20Token.json new file mode 100644 index 00000000..3c4bbc4e --- /dev/null +++ b/abi/ITestnetERC20Token.json @@ -0,0 +1,39 @@ +[ + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/IZkSync.json b/abi/IZkSyncStateTransition.json similarity index 63% rename from abi/IZkSync.json rename to abi/IZkSyncStateTransition.json index f6480098..d7f8622d 100644 --- a/abi/IZkSync.json +++ b/abi/IZkSyncStateTransition.json @@ -206,38 +206,114 @@ "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "oldGovernor", - "type": "address" + "indexed": false, + "internalType": "uint128", + "name": "oldNominator", + "type": "uint128" }, { - "indexed": true, - "internalType": "address", - "name": "newGovernor", - "type": "address" + "indexed": false, + "internalType": "uint128", + "name": "oldDenominator", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "newNominator", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "newDenominator", + "type": "uint128" } ], - "name": "NewGovernor", + "name": "NewBaseTokenMultiplier", "type": "event" }, { "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "oldPendingAdmin", - "type": "address" + "components": [ + { + "internalType": "enum PubdataPricingMode", + "name": "pubdataPricingMode", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "batchOverheadL1Gas", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxPubdataPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxL2GasPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "priorityTxMaxPubdata", + "type": "uint32" + }, + { + "internalType": "uint64", + "name": "minimalL2GasPrice", + "type": "uint64" + } + ], + "indexed": false, + "internalType": "struct FeeParams", + "name": "oldFeeParams", + "type": "tuple" }, { - "indexed": true, - "internalType": "address", - "name": "newPendingAdmin", - "type": "address" + "components": [ + { + "internalType": "enum PubdataPricingMode", + "name": "pubdataPricingMode", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "batchOverheadL1Gas", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxPubdataPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxL2GasPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "priorityTxMaxPubdata", + "type": "uint32" + }, + { + "internalType": "uint64", + "name": "minimalL2GasPrice", + "type": "uint64" + } + ], + "indexed": false, + "internalType": "struct FeeParams", + "name": "newFeeParams", + "type": "tuple" } ], - "name": "NewPendingAdmin", + "name": "NewFeeParams", "type": "event" }, { @@ -246,17 +322,17 @@ { "indexed": true, "internalType": "address", - "name": "oldPendingGovernor", + "name": "oldPendingAdmin", "type": "address" }, { "indexed": true, "internalType": "address", - "name": "newPendingGovernor", + "name": "newPendingAdmin", "type": "address" } ], - "name": "NewPendingGovernor", + "name": "NewPendingAdmin", "type": "event" }, { @@ -364,7 +440,7 @@ } ], "indexed": false, - "internalType": "struct IMailbox.L2CanonicalTransaction", + "internalType": "struct L2CanonicalTransaction", "name": "transaction", "type": "tuple" }, @@ -397,6 +473,89 @@ "name": "NewPriorityTxMaxGasLimit", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldTransactionFilterer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newTransactionFilterer", + "type": "address" + } + ], + "name": "NewTransactionFilterer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "facet", + "type": "address" + }, + { + "internalType": "enum Diamond.Action", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "isFreezable", + "type": "bool" + }, + { + "internalType": "bytes4[]", + "name": "selectors", + "type": "bytes4[]" + } + ], + "internalType": "struct Diamond.FacetCut[]", + "name": "facetCuts", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "initAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "initCalldata", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct Diamond.DiamondCutData", + "name": "diamondCut", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "proposalSalt", + "type": "bytes32" + } + ], + "name": "ProposeTransparentUpgrade", + "type": "event" + }, { "anonymous": false, "inputs": [], @@ -422,6 +581,19 @@ "name": "ValidatorStatusUpdate", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum PubdataPricingMode", + "name": "validiumMode", + "type": "uint8" + } + ], + "name": "ValidiumModeStatusUpdate", + "type": "event" + }, { "inputs": [], "name": "acceptAdmin", @@ -431,7 +603,137 @@ }, { "inputs": [], - "name": "acceptGovernor", + "name": "baseTokenGasPriceMultiplierDenominator", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseTokenGasPriceMultiplierNominator", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "contractL2", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2Value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "l2Calldata", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "l2GasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2GasPerPubdataByteLimit", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "factoryDeps", + "type": "bytes[]" + }, + { + "internalType": "address", + "name": "refundRecipient", + "type": "address" + } + ], + "internalType": "struct BridgehubL2TransactionRequest", + "name": "_request", + "type": "tuple" + } + ], + "name": "bridgehubRequestL2Transaction", + "outputs": [ + { + "internalType": "bytes32", + "name": "canonicalTxHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum PubdataPricingMode", + "name": "pubdataPricingMode", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "batchOverheadL1Gas", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxPubdataPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxL2GasPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "priorityTxMaxPubdata", + "type": "uint32" + }, + { + "internalType": "uint64", + "name": "minimalL2GasPrice", + "type": "uint64" + } + ], + "internalType": "struct FeeParams", + "name": "_newFeeParams", + "type": "tuple" + } + ], + "name": "changeFeeParams", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -534,7 +836,7 @@ }, { "internalType": "bytes", - "name": "totalL2ToL1Pubdata", + "name": "pubdataCommitments", "type": "bytes" } ], @@ -548,6 +850,123 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo", + "name": "_lastCommittedBatchData", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "timestamp", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "newStateRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "bootloaderHeapInitialContentsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "eventsQueueStateHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "systemLogs", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "pubdataCommitments", + "type": "bytes" + } + ], + "internalType": "struct IExecutor.CommitBatchInfo[]", + "name": "_newBatchesData", + "type": "tuple[]" + } + ], + "name": "commitBatchesSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -603,6 +1022,66 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo[]", + "name": "_batchesData", + "type": "tuple[]" + } + ], + "name": "executeBatchesSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -773,12 +1252,12 @@ }, { "inputs": [], - "name": "getFirstUnprocessedPriorityTx", + "name": "getAdmin", "outputs": [ { - "internalType": "uint256", + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "stateMutability": "view", @@ -786,12 +1265,51 @@ }, { "inputs": [], - "name": "getGovernor", + "name": "getBaseToken", "outputs": [ { "internalType": "address", "name": "", - "type": "address" + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBaseTokenBridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBridgehub", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFirstUnprocessedPriorityTx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" } ], "stateMutability": "view", @@ -864,7 +1382,7 @@ }, { "inputs": [], - "name": "getPendingGovernor", + "name": "getPendingAdmin", "outputs": [ { "internalType": "address", @@ -914,6 +1432,32 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getPubdataPricingMode", + "outputs": [ + { + "internalType": "enum PubdataPricingMode", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStateTransitionManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getTotalBatchesCommitted", @@ -1115,7 +1659,7 @@ "outputs": [ { "internalType": "bytes32", - "name": "hash", + "name": "merkleRoot", "type": "bytes32" } ], @@ -1300,6 +1844,130 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo", + "name": "_prevBatch", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo[]", + "name": "_committedBatches", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256[]", + "name": "recursiveAggregationInput", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "serializedProof", + "type": "uint256[]" + } + ], + "internalType": "struct IExecutor.ProofInput", + "name": "_proof", + "type": "tuple" + } + ], + "name": "proveBatchesSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1348,7 +2016,7 @@ "inputs": [ { "internalType": "uint256", - "name": "_l2BatchNumber", + "name": "_batchNumber", "type": "uint256" }, { @@ -1414,7 +2082,7 @@ "inputs": [ { "internalType": "uint256", - "name": "_l2BatchNumber", + "name": "_batchNumber", "type": "uint256" }, { @@ -1526,12 +2194,17 @@ { "inputs": [ { - "internalType": "address", - "name": "_newPendingAdmin", - "type": "address" + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_newLastBatch", + "type": "uint256" } ], - "name": "setPendingAdmin", + "name": "revertBatchesSharedBridge", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1540,11 +2213,11 @@ "inputs": [ { "internalType": "address", - "name": "_newPendingGovernor", + "name": "_newPendingAdmin", "type": "address" } ], - "name": "setPendingGovernor", + "name": "setPendingAdmin", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1575,6 +2248,37 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "_nominator", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "_denominator", + "type": "uint128" + } + ], + "name": "setTokenMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_transactionFilterer", + "type": "address" + } + ], + "name": "setTransactionFilterer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1593,6 +2297,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "enum PubdataPricingMode", + "name": "_validiumMode", + "type": "uint8" + } + ], + "name": "setValidiumMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1612,11 +2329,75 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "transferEthToSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "unfreezeDiamond", "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_protocolVersion", + "type": "uint256" + }, + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "facet", + "type": "address" + }, + { + "internalType": "enum Diamond.Action", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "isFreezable", + "type": "bool" + }, + { + "internalType": "bytes4[]", + "name": "selectors", + "type": "bytes4[]" + } + ], + "internalType": "struct Diamond.FacetCut[]", + "name": "facetCuts", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "initAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "initCalldata", + "type": "bytes" + } + ], + "internalType": "struct Diamond.DiamondCutData", + "name": "_cutData", + "type": "tuple" + } + ], + "name": "upgradeChainFromVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ] diff --git a/package.json b/package.json index 54b5115b..d93a9baa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zksync-ethers", - "version": "6.7.0", + "version": "6.8.0-beta.1", "main": "build/index.js", "types": "build/index.d.ts", "description": "A Web3 library for interacting with the ZkSync Layer 2 scaling solution.", @@ -30,7 +30,8 @@ "files": [ "build/", "abi/", - "src/" + "src/", + "typechain" ], "dependencies": {}, "devDependencies": { @@ -66,7 +67,7 @@ "lint:fix": "gts fix", "watch": "tsc --watch", "types:fetch": "cd scripts && ./update-abi.sh && cd ../", - "types": "typechain --target ethers-v6 --out-dir src/typechain src/abi/*.json", + "types": "typechain --target ethers-v6 --out-dir src/typechain abi/*.json && ncp src/typechain typechain", "clean": "gts clean", "docs": "typedoc --out docs --hideInPageTOC true --useCodeBlocks true --includeVersion true src/index.ts && cd scripts && ./post-process-doc.sh && cd ../" }, diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index ede263b0..bfa96e0c 100755 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -16,11 +16,15 @@ yarn install echo "Generate ABIs" solc --base-path l1-contracts/ \ - --include-path ./node_modules/ \ + --include-path l1-contracts/node_modules/ \ -o l1-abi \ --abi \ - l1-contracts/contracts/zksync/interfaces/IZkSync.sol \ - l1-contracts/contracts/bridge/interfaces/IL1Bridge.sol \ + l1-contracts/contracts/bridgehub/IBridgehub.sol \ + l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncStateTransition.sol \ + l1-contracts/contracts/dev-contracts/interfaces/ITestnetERC20Token.sol \ + l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol \ + l1-contracts/contracts/bridge/interfaces/IL1WethBridge.sol \ + l1-contracts/contracts/bridge/interfaces/IL1Erc20Bridge.sol \ l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol solc --base-path system-contracts \ @@ -35,7 +39,7 @@ solc --base-path system-contracts \ mkdir abi /abi mv l1-abi/* system-contracts-abi/* abi -contracts="IZkSync.abi IL1Bridge.abi IL2Bridge.abi IContractDeployer.abi IEthToken.abi IL1Messenger.abi INonceHolder.abi IPaymasterFlow.abi" +contracts="IBridgehub.abi IZkSyncStateTransition.abi IL1ERC20Bridge.abi IL1WethBridge.abi IL1Erc20Bridge.abi IL2Bridge.abi IContractDeployer.abi IEthToken.abi IL1Messenger.abi INonceHolder.abi IPaymasterFlow.abi ITestnetERC20Token.abi" for filename in $contracts; do jq '.' "abi/$filename" > "/abi/${filename%.abi}.json" diff --git a/src/adapters.ts b/src/adapters.ts index 2095b562..4bae9404 100644 --- a/src/adapters.ts +++ b/src/adapters.ts @@ -25,16 +25,23 @@ import { scaleGasLimit, undoL1ToL2Alias, NONCE_HOLDER_ADDRESS, + ETH_ADDRESS_IN_CONTRACTS, + LEGACY_ETH_ADDRESS, } from './utils'; import { + IBridgehub, + IBridgehub__factory, IERC20__factory, - IL1Bridge, + IL1ERC20Bridge, + IL1ERC20Bridge__factory, IL1Bridge__factory, + IL1SharedBridge, + IL1SharedBridge__factory, IL2Bridge, IL2Bridge__factory, INonceHolder__factory, - IZkSync, - IZkSync__factory, + IZkSyncStateTransition, + IZkSyncStateTransition__factory, } from './typechain'; import { Address, @@ -83,24 +90,57 @@ export function AdapterL1>(Base: TBase) { /** * Returns `Contract` wrapper of the zkSync Era smart contract. */ - async getMainContract(): Promise { + async getMainContract(): Promise { const address = await this._providerL2().getMainContractAddress(); - return IZkSync__factory.connect(address, this._signerL1()); + return IZkSyncStateTransition__factory.connect(address, this._signerL1()); + } + + /** + * Returns `Contract` wrapper of the Bridgehub smart contract. + */ + async getBridgehubContract(): Promise { + const address = await this._providerL2().getBridgehubContractAddress(); + return IBridgehub__factory.connect(address, this._signerL1()); } /** * Returns L1 bridge contracts. * - * @remarks There is no separate Ether bridge contract, {@link getMainContract Main contract} is used instead. + * @remarks There is no separate Ether bridge contract, {@link getBridgehubContract Bridgehub} is used instead. */ - async getL1BridgeContracts(): Promise<{erc20: IL1Bridge; weth: IL1Bridge}> { + async getL1BridgeContracts(): Promise<{ + erc20: IL1ERC20Bridge; + shared: IL1SharedBridge; + }> { const addresses = await this._providerL2().getDefaultBridgeAddresses(); return { - erc20: IL1Bridge__factory.connect(addresses.erc20L1!, this._signerL1()), - weth: IL1Bridge__factory.connect(addresses.wethL1!, this._signerL1()), + erc20: IL1ERC20Bridge__factory.connect( + addresses.erc20L1, + this._signerL1() + ), + shared: IL1SharedBridge__factory.connect( + addresses.sharedL1, + this._signerL1() + ), }; } + /** + * Returns the address of the base token on L1. + */ + async getBaseToken(): Promise { + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + return await bridgehub.baseToken(chainId); + } + + /** + * Returns whether the chain is ETH-based. + */ + async isETHBasedChain(): Promise { + return this._providerL2().isEthBasedChain(); + } + /** * Returns the amount of the token held by the account on the L1 network. * @@ -109,7 +149,7 @@ export function AdapterL1>(Base: TBase) { * Defaults to 'committed', i.e., the latest processed block. */ async getBalanceL1(token?: Address, blockTag?: BlockTag): Promise { - token ??= ETH_ADDRESS; + token ??= LEGACY_ETH_ADDRESS; if (isETH(token)) { return await this._providerL1().getBalance( await this.getAddress(), @@ -140,18 +180,7 @@ export function AdapterL1>(Base: TBase) { ): Promise { if (!bridgeAddress) { const bridgeContracts = await this.getL1BridgeContracts(); - let l2WethToken = ethers.ZeroAddress; - try { - l2WethToken = await bridgeContracts.weth.l2TokenAddress(token); - } catch (e) { - // skip - } - - // If the token is Wrapped Ether, return allowance to its own bridge, otherwise to the default ERC20 bridge. - bridgeAddress = - l2WethToken !== ethers.ZeroAddress - ? await bridgeContracts.weth.getAddress() - : await bridgeContracts.erc20.getAddress(); + bridgeAddress = await bridgeContracts.shared.getAddress(); } const erc20contract = IERC20__factory.connect(token, this._providerL1()); @@ -173,20 +202,7 @@ export function AdapterL1>(Base: TBase) { * @param token The address of the token on L1. */ async l2TokenAddress(token: Address): Promise { - if (token === ETH_ADDRESS) { - return ETH_ADDRESS; - } - const bridgeContracts = await this.getL1BridgeContracts(); - try { - const l2WethToken = await bridgeContracts.weth.l2TokenAddress(token); - // If the token is Wrapped Ether, return its L2 token address. - if (l2WethToken !== ethers.ZeroAddress) { - return l2WethToken; - } - } catch (e) { - // skip - } - return await bridgeContracts.erc20.l2TokenAddress(token); + return this._providerL2().l2TokenAddress(token); } /** @@ -210,27 +226,25 @@ export function AdapterL1>(Base: TBase) { } overrides ??= {}; - let bridgeAddress = overrides?.bridgeAddress; + let bridgeAddress = overrides.bridgeAddress; const erc20contract = IERC20__factory.connect(token, this._signerL1()); + const baseToken = await this.getBaseToken(); + const isETHBasedChain = await this.isETHBasedChain(); if (!bridgeAddress) { - const bridgeContracts = await this.getL1BridgeContracts(); - let l2WethToken = ethers.ZeroAddress; - try { - l2WethToken = await bridgeContracts.weth.l2TokenAddress(token); - } catch (e) { - // skip + if (!isETHBasedChain && token === baseToken) { + bridgeAddress = await ( + await this.getBridgehubContract() + ).sharedBridge(); + } else { + const bridgeContracts = await this.getL1BridgeContracts(); + bridgeAddress = await bridgeContracts.shared.getAddress(); } - // If the token is Wrapped Ether, return corresponding bridge, otherwise return default ERC20 bridge - bridgeAddress = - l2WethToken !== ethers.ZeroAddress - ? await bridgeContracts.weth.getAddress() - : await bridgeContracts.erc20.getAddress(); } else { delete overrides.bridgeAddress; } - return await erc20contract.approve(bridgeAddress!, amount, overrides); + return await erc20contract.approve(bridgeAddress, amount, overrides); } /** @@ -246,25 +260,92 @@ export function AdapterL1>(Base: TBase) { gasPerPubdataByte?: BigNumberish; gasPrice?: BigNumberish; }): Promise { - const zksyncContract = await this.getMainContract(); + const bridgehub = await this.getBridgehubContract(); const parameters = {...layer1TxDefaults(), ...params}; parameters.gasPrice ??= (await this._providerL1().getFeeData()).gasPrice!; parameters.gasPerPubdataByte ??= REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; - return await zksyncContract.l2TransactionBaseCost( + return await bridgehub.l2TransactionBaseCost( + (await this._providerL2().getNetwork()).chainId, parameters.gasPrice, parameters.gasLimit, parameters.gasPerPubdataByte ); } + /** + * Returns the parameters for the approval token transaction based on the deposit token and amount. + * Some deposit transactions require multiple approvals. Existing allowance for the bridge is not checked; + * allowance is calculated solely based on the specified amount. + * + * @param token The address of the token to deposit. + * @param amount The amount of the token to deposit. + */ + async getDepositAllowanceParams( + token: Address, + amount: BigNumberish + ): Promise<{token: Address; allowance: BigNumberish}[]> { + if (token === LEGACY_ETH_ADDRESS) { + token = ETH_ADDRESS_IN_CONTRACTS; + } + const baseTokenAddress = await this.getBaseToken(); + const isETHBasedChain = await this.isETHBasedChain(); + + if (isETHBasedChain && token === LEGACY_ETH_ADDRESS) { + throw new Error( + "ETH token can't be approved! The address of the token does not exist on L1." + ); + } else if (baseTokenAddress === ETH_ADDRESS_IN_CONTRACTS) { + return [{token, allowance: amount}]; + } else if (token === LEGACY_ETH_ADDRESS) { + return [ + { + token: baseTokenAddress, + allowance: ( + await this._getDepositETHOnNonETHBasedChainTx({token, amount}) + ).mintValue, + }, + ]; + } else if (token === baseTokenAddress) { + return [ + { + token: baseTokenAddress, + allowance: ( + await this._getDepositBaseTokenOnNonETHBasedChainTx({ + token, + amount, + }) + ).mintValue, + }, + ]; + } else { + // A deposit of a non-base token to a non-ETH-based chain requires two approvals. + return [ + { + token: baseTokenAddress, + allowance: ( + await this._getDepositNonBaseTokenToNonETHBasedChainTx({ + token, + amount, + }) + ).mintValue, + }, + { + token: token, + allowance: amount, + }, + ]; + } + } + /** * Transfers the specified token from the associated account on the L1 network to the target account on the L2 network. * The token can be either ETH or any ERC20 token. For ERC20 tokens, enough approved tokens must be associated with * the specified L1 bridge (default one or the one defined in `transaction.bridgeAddress`). - * In this case, `transaction.approveERC20` can be enabled to perform token approval. If there are already enough - * approved tokens for the L1 bridge, token approval will be skipped. - * To check the amount of approved tokens for a specific bridge, use the {@link getAllowanceL1} method. + * In this case, depending on is the chain ETH-based or not `transaction.approveERC20` or `transaction.approveBaseERC20` + * can be enabled to perform token approval. If there are already enough approved tokens for the L1 bridge, + * token approval will be skipped. To check the amount of approved tokens for a specific bridge, + * use the {@link getAllowanceL1} method. * * @param transaction The transaction object containing deposit details. * @param transaction.token The address of the token to deposit. ETH by default. @@ -276,13 +357,19 @@ export function AdapterL1>(Base: TBase) { * @param [transaction.bridgeAddress] The address of the bridge contract to be used. * Defaults to the default zkSync Era bridge (either `L1EthBridge` or `L1Erc20Bridge`). * @param [transaction.approveERC20] Whether or not token approval should be performed under the hood. - * Set this flag to true if you bridge an ERC20 token and didn't call the {@link approveERC20} function beforehand. + * Set this flag to true if you bridge an ERC20 token and didn't call the {@link approveERC20} function beforehand. + * @param [transaction.approveBaseERC20] Whether or not base token approval should be performed under the hood. + * Set this flag to true if you bridge a base token and didn't call the {@link approveERC20} function beforehand. * @param [transaction.l2GasLimit] Maximum amount of L2 gas that the transaction can consume during execution on L2. * @param [transaction.gasPerPubdataByte] The L2 gas price for each published L1 calldata byte. * @param [transaction.refundRecipient] The address on L2 that will receive the refund for the transaction. * If the transaction fails, it will also be the address to receive `l2Value`. - * @param [transaction.overrides] Transaction's overrides which may be used to pass L1 `gasLimit`, `gasPrice`, `value`, etc. - * @param [transaction.approveOverrides] Transaction's overrides which may be used to pass L1 `gasLimit`, `gasPrice`, `value`, etc. + * @param [transaction.overrides] Transaction's overrides for deposit which may be used to pass + * L1 `gasLimit`, `gasPrice`, `value`, etc. + * @param [transaction.approveOverrides] Transaction's overrides for approval of an ERC20 token which may be used + * to pass L1 `gasLimit`, `gasPrice`, `value`, etc. + * @param [transaction.approveBaseOverrides] Transaction's overrides for approval of a base token which may be used + * to pass L1 `gasLimit`, `gasPrice`, `value`, etc. * @param [transaction.customBridgeData] Additional data that can be sent to a bridge. */ async deposit(transaction: { @@ -292,73 +379,307 @@ export function AdapterL1>(Base: TBase) { operatorTip?: BigNumberish; bridgeAddress?: Address; approveERC20?: boolean; + approveBaseERC20?: boolean; l2GasLimit?: BigNumberish; gasPerPubdataByte?: BigNumberish; refundRecipient?: Address; overrides?: ethers.Overrides; approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; customBridgeData?: BytesLike; }): Promise { - const depositTx = await this.getDepositTx(transaction); - - if (transaction.token === ETH_ADDRESS) { - const baseGasLimit = await this.estimateGasRequestExecute(depositTx); - const gasLimit = scaleGasLimit(baseGasLimit); - depositTx.overrides.gasLimit ??= gasLimit; - return this.requestExecute(depositTx); + if (transaction.token === LEGACY_ETH_ADDRESS) { + transaction.token = ETH_ADDRESS_IN_CONTRACTS; + } + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const isETHBasedChain = baseTokenAddress === ETH_ADDRESS_IN_CONTRACTS; + + if (isETHBasedChain && transaction.token === ETH_ADDRESS_IN_CONTRACTS) { + return await this._depositETHToETHBasedChain(transaction); + } else if (baseTokenAddress === ETH_ADDRESS_IN_CONTRACTS) { + return await this._depositTokenToETHBasedChain(transaction); + } else if (transaction.token === ETH_ADDRESS_IN_CONTRACTS) { + return await this._depositETHToNonETHBasedChain(transaction); + } else if (transaction.token === baseTokenAddress) { + return await this._depositBaseTokenToNonETHBasedChain(transaction); } else { - const bridgeContracts = await this.getL1BridgeContracts(); - if (transaction.approveERC20) { - let l2WethToken = ethers.ZeroAddress; - try { - l2WethToken = await bridgeContracts.weth.l2TokenAddress( - transaction.token - ); - } catch (e) { - // skip - } - // If the token is Wrapped Ether, use its bridge. - const proposedBridge = - l2WethToken !== ethers.ZeroAddress - ? await bridgeContracts.weth.getAddress() - : await bridgeContracts.erc20.getAddress(); - const bridgeAddress = transaction.bridgeAddress - ? transaction.bridgeAddress - : proposedBridge; - - // We only request the allowance if the current one is not enough. - const allowance = await this.getAllowanceL1( + return await this._depositNonBaseTokenToNonETHBasedChain(transaction); + } + } + + async _depositNonBaseTokenToNonETHBasedChain(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + approveERC20?: boolean; + approveBaseERC20?: boolean; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; + customBridgeData?: BytesLike; + }): Promise { + // Deposit a non-ETH and non-base token to a non-ETH-based chain. + // Go through the BridgeHub and obtain approval for both tokens. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const bridgeContracts = await this.getL1BridgeContracts(); + const {tx, mintValue} = + await this._getDepositNonBaseTokenToNonETHBasedChainTx(transaction); + + if (transaction.approveBaseERC20) { + // Only request the allowance if the current one is not enough. + const allowance = await this.getAllowanceL1( + baseTokenAddress, + await bridgeContracts.shared.getAddress() + ); + if (allowance < mintValue) { + const approveTx = await this.approveERC20( + baseTokenAddress, + mintValue, + { + bridgeAddress: await bridgeContracts.shared.getAddress(), + ...transaction.approveBaseOverrides, + } + ); + await approveTx.wait(); + } + } + + if (transaction.approveERC20) { + const bridgeAddress = transaction.bridgeAddress + ? transaction.bridgeAddress + : await bridgeContracts.shared.getAddress(); + + // Only request the allowance if the current one is not enough. + const allowance = await this.getAllowanceL1( + transaction.token, + bridgeAddress + ); + if (allowance < BigInt(transaction.amount)) { + const approveTx = await this.approveERC20( transaction.token, - bridgeAddress + transaction.amount, + { + bridgeAddress, + ...transaction.approveOverrides, + } ); - if (allowance < BigInt(transaction.amount)) { - const approveTx = await this.approveERC20( - transaction.token, - transaction.amount, - { - bridgeAddress, - ...transaction.approveOverrides, - } - ); - await approveTx.wait(); - } + await approveTx.wait(); + } + } + + const baseGasLimit = await this._providerL1().estimateGas(tx); + const gasLimit = scaleGasLimit(baseGasLimit); + + tx.gasLimit ??= gasLimit; + + return await this._providerL2().getPriorityOpResponse( + await this._signerL1().sendTransaction(tx) + ); + } + + async _depositBaseTokenToNonETHBasedChain(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + approveERC20?: boolean; + approveBaseERC20?: boolean; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; + customBridgeData?: BytesLike; + }): Promise { + // Bridging the base token to a non-ETH-based chain. + // Go through the BridgeHub, and give approval. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const sharedBridge = await bridgehub.sharedBridge(); + const {tx, mintValue} = + await this._getDepositBaseTokenOnNonETHBasedChainTx(transaction); + + if (transaction.approveERC20 || transaction.approveBaseERC20) { + // Only request the allowance if the current one is not enough. + const allowance = await this.getAllowanceL1( + baseTokenAddress, + sharedBridge + ); + if (allowance < mintValue) { + const approveTx = await this.approveERC20( + baseTokenAddress, + mintValue, + { + bridgeAddress: sharedBridge, + ...transaction.approveBaseOverrides, + } + ); + await approveTx.wait(); } + } + const baseGasLimit = await this.estimateGasRequestExecute(tx); + const gasLimit = scaleGasLimit(baseGasLimit); - const baseGasLimit = await this._providerL1().estimateGas(depositTx); - const gasLimit = scaleGasLimit(baseGasLimit); + tx.overrides ??= {}; + tx.overrides.gasLimit ??= gasLimit; - depositTx.gasLimit ??= gasLimit; + return this.requestExecute(tx); + } - return await this._providerL2().getPriorityOpResponse( - await this._signerL1().sendTransaction(depositTx) + async _depositETHToNonETHBasedChain(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + approveERC20?: boolean; + approveBaseERC20?: boolean; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; + customBridgeData?: BytesLike; + }): Promise { + // Depositing ETH into a non-ETH-based chain. + // Use requestL2TransactionTwoBridges, secondBridge is the wETH bridge. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const sharedBridge = await bridgehub.sharedBridge(); + const {tx, mintValue} = + await this._getDepositETHOnNonETHBasedChainTx(transaction); + + if (transaction.approveBaseERC20) { + // Only request the allowance if the current one is not enough. + const allowance = await this.getAllowanceL1( + baseTokenAddress, + sharedBridge + ); + if (allowance < mintValue) { + const approveTx = await this.approveERC20( + baseTokenAddress, + mintValue, + { + bridgeAddress: sharedBridge, + ...transaction.approveBaseOverrides, + } + ); + await approveTx.wait(); + } + } + + const baseGasLimit = await this._providerL1().estimateGas(tx); + const gasLimit = scaleGasLimit(baseGasLimit); + + tx.gasLimit ??= gasLimit; + + return await this._providerL2().getPriorityOpResponse( + await this._signerL1().sendTransaction(tx) + ); + } + + async _depositTokenToETHBasedChain(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + approveERC20?: boolean; + approveBaseERC20?: boolean; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; + customBridgeData?: BytesLike; + }): Promise { + const bridgeContracts = await this.getL1BridgeContracts(); + const tx = await this._getDepositTokenOnETHBasedChainTx(transaction); + + if (transaction.approveERC20) { + const proposedBridge = await bridgeContracts.shared.getAddress(); + const bridgeAddress = transaction.bridgeAddress + ? transaction.bridgeAddress + : proposedBridge; + + // Only request the allowance if the current one is not enough. + const allowance = await this.getAllowanceL1( + transaction.token, + bridgeAddress ); + if (allowance < BigInt(transaction.amount)) { + const approveTx = await this.approveERC20( + transaction.token, + transaction.amount, + { + bridgeAddress, + ...transaction.approveOverrides, + } + ); + await approveTx.wait(); + } } + + const baseGasLimit = await this._providerL1().estimateGas(tx); + const gasLimit = scaleGasLimit(baseGasLimit); + + tx.gasLimit ??= gasLimit; + + return await this._providerL2().getPriorityOpResponse( + await this._signerL1().sendTransaction(tx) + ); + } + + async _depositETHToETHBasedChain(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + approveERC20?: boolean; + approveBaseERC20?: boolean; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; + customBridgeData?: BytesLike; + }): Promise { + const tx = await this._getDepositETHOnETHBasedChainTx(transaction); + + const baseGasLimit = await this.estimateGasRequestExecute(tx); + const gasLimit = scaleGasLimit(baseGasLimit); + + tx.overrides ??= {}; + tx.overrides.gasLimit ??= gasLimit; + + return this.requestExecute(tx); } /** * Estimates the amount of gas required for a deposit transaction on the L1 network. * Gas for approving ERC20 tokens is not included in the estimation. * + * In order for estimation to work, enough token allowance is required in the following cases: + * - Depositing ERC20 tokens on an ETH-based chain. + * - Depositing any token (including ETH) on a non-ETH-based chain. + * * @param transaction The transaction details. * @param transaction.token The address of the token to deposit. ETH by default. * @param transaction.amount The amount of the token to deposit. @@ -387,13 +708,16 @@ export function AdapterL1>(Base: TBase) { refundRecipient?: Address; overrides?: ethers.Overrides; }): Promise { - const depositTx = await this.getDepositTx(transaction); + if (transaction.token === LEGACY_ETH_ADDRESS) { + transaction.token = ETH_ADDRESS_IN_CONTRACTS; + } + const tx = await this.getDepositTx(transaction); let baseGasLimit: bigint; - if (transaction.token === ETH_ADDRESS) { - baseGasLimit = await this.estimateGasRequestExecute(depositTx); + if (tx.token === (await this.getBaseToken())) { + baseGasLimit = await this.estimateGasRequestExecute(tx); } else { - baseGasLimit = await this._providerL1().estimateGas(depositTx); + baseGasLimit = await this._providerL1().estimateGas(tx); } return scaleGasLimit(baseGasLimit); @@ -430,114 +754,441 @@ export function AdapterL1>(Base: TBase) { refundRecipient?: Address; overrides?: ethers.Overrides; }): Promise { - const bridgeContracts = await this.getL1BridgeContracts(); - if (transaction.bridgeAddress) { - bridgeContracts.erc20 = bridgeContracts.erc20.attach( - transaction.bridgeAddress - ) as IL1Bridge; + if (transaction.token === LEGACY_ETH_ADDRESS) { + transaction.token = ETH_ADDRESS_IN_CONTRACTS; } - - const {...tx} = transaction; - tx.to ??= await this.getAddress(); - tx.operatorTip ??= 0; - tx.overrides ??= {}; - tx.overrides.from ??= await this.getAddress(); - tx.gasPerPubdataByte ??= REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; - if (tx.bridgeAddress) { - const customBridgeData = - tx.customBridgeData ?? - (await bridgeContracts.weth.getAddress()) === tx.bridgeAddress - ? '0x' - : await getERC20DefaultBridgeData(tx.token, this._providerL1()); - const bridge = IL1Bridge__factory.connect( - tx.bridgeAddress, - this._signerL1() - ); - const l2Address = await bridge.l2Bridge(); - tx.l2GasLimit ??= await estimateCustomBridgeDepositL2Gas( - this._providerL2(), - tx.bridgeAddress, - l2Address, - tx.token, - tx.amount, - tx.to, - customBridgeData, - await this.getAddress(), - tx.gasPerPubdataByte - ); + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const isETHBasedChain = baseTokenAddress === ETH_ADDRESS_IN_CONTRACTS; + + if (isETHBasedChain && transaction.token === ETH_ADDRESS_IN_CONTRACTS) { + return await this._getDepositETHOnETHBasedChainTx(transaction); + } else if (isETHBasedChain) { + return await this._getDepositTokenOnETHBasedChainTx(transaction); + } else if (transaction.token === ETH_ADDRESS_IN_CONTRACTS) { + return (await this._getDepositETHOnNonETHBasedChainTx(transaction)).tx; + } else if (transaction.token === baseTokenAddress) { + return ( + await this._getDepositBaseTokenOnNonETHBasedChainTx(transaction) + ).tx; } else { - tx.l2GasLimit ??= await estimateDefaultBridgeDepositL2Gas( - this._providerL1(), - this._providerL2(), - tx.token, - tx.amount, - tx.to, - await this.getAddress(), - tx.gasPerPubdataByte - ); + return ( + await this._getDepositNonBaseTokenToNonETHBasedChainTx(transaction) + ).tx; } + } - const {to, token, amount, operatorTip, overrides} = tx; + async _getDepositNonBaseTokenToNonETHBasedChainTx(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }) { + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const bridgeContracts = await this.getL1BridgeContracts(); + + const tx = await this._getDepositTxWithDefaults(transaction); + const { + token, + operatorTip, + amount, + overrides, + l2GasLimit, + to, + refundRecipient, + gasPerPubdataByte, + } = tx; - await insertGasPrice(this._providerL1(), overrides); const gasPriceForEstimation = overrides.maxFeePerGas || overrides.gasPrice; + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + l2GasLimit, + gasPerPubdataByte + ); - const zksyncContract = await this.getMainContract(); + const mintValue = baseCost + BigInt(operatorTip); + await checkBaseCost(baseCost, mintValue); + overrides.value ??= 0; - const baseCost = await zksyncContract.l2TransactionBaseCost( - gasPriceForEstimation!, - tx.l2GasLimit, - tx.gasPerPubdataByte - ); + return { + tx: await bridgehub.requestL2TransactionTwoBridges.populateTransaction( + { + chainId: chainId, + mintValue, + l2Value: 0, + l2GasLimit: l2GasLimit, + l2GasPerPubdataByteLimit: gasPerPubdataByte, + refundRecipient: refundRecipient ?? ethers.ZeroAddress, + secondBridgeAddress: await bridgeContracts.shared.getAddress(), + secondBridgeValue: 0, + secondBridgeCalldata: ethers.AbiCoder.defaultAbiCoder().encode( + ['address', 'uint256', 'address'], + [token, amount, to] + ), + }, + overrides + ), + mintValue: mintValue, + }; + } - if (token === ETH_ADDRESS) { - overrides.value ??= baseCost + BigInt(operatorTip) + BigInt(amount); + async _getDepositBaseTokenOnNonETHBasedChainTx(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }) { + // Depositing the base token to a non-ETH-based chain. + // Goes through the BridgeHub. + // Have to give approvals for the sharedBridge. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + + const tx = await this._getDepositTxWithDefaults(transaction); + const { + operatorTip, + amount, + to, + overrides, + l2GasLimit, + gasPerPubdataByte, + } = tx; - return { + const gasPriceForEstimation = + overrides.maxFeePerGas || overrides.gasPrice; + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + l2GasLimit, + gasPerPubdataByte + ); + + tx.overrides.value = 0; + return { + tx: { contractAddress: to, calldata: '0x', + mintValue: baseCost + BigInt(operatorTip) + BigInt(amount), l2Value: amount, ...tx, - }; + }, + mintValue: baseCost + BigInt(operatorTip) + BigInt(amount), + }; + } + + async _getDepositETHOnNonETHBasedChainTx(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }) { + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const sharedBridge = (await this.getL1BridgeContracts()).shared; + + const tx = await this._getDepositTxWithDefaults(transaction); + const { + operatorTip, + amount, + overrides, + l2GasLimit, + to, + refundRecipient, + gasPerPubdataByte, + } = tx; + + const gasPriceForEstimation = + overrides.maxFeePerGas || overrides.gasPrice; + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + l2GasLimit, + gasPerPubdataByte + ); + + overrides.value ??= amount; + const mintValue = baseCost + BigInt(operatorTip); + await checkBaseCost(baseCost, mintValue); + + return { + tx: await bridgehub.requestL2TransactionTwoBridges.populateTransaction( + { + chainId, + mintValue, + l2Value: 0, + l2GasLimit: l2GasLimit, + l2GasPerPubdataByteLimit: gasPerPubdataByte, + refundRecipient: refundRecipient ?? ethers.ZeroAddress, + secondBridgeAddress: await sharedBridge.getAddress(), + secondBridgeValue: amount, + secondBridgeCalldata: ethers.AbiCoder.defaultAbiCoder().encode( + ['address', 'uint256', 'address'], + [ETH_ADDRESS_IN_CONTRACTS, 0, to] + ), + }, + overrides + ), + mintValue: mintValue, + }; + } + + async _getDepositTokenOnETHBasedChainTx(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }): Promise { + // Depositing token to an ETH-based chain. Use the ERC20 bridge as done before. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + + const tx = await this._getDepositTxWithDefaults(transaction); + const { + token, + operatorTip, + amount, + overrides, + l2GasLimit, + to, + refundRecipient, + gasPerPubdataByte, + } = tx; + + const gasPriceForEstimation = + overrides.maxFeePerGas || overrides.gasPrice; + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + tx.l2GasLimit, + tx.gasPerPubdataByte + ); + + const mintValue = baseCost + BigInt(operatorTip); + overrides.value ??= mintValue; + await checkBaseCost(baseCost, mintValue); + + let secondBridgeAddress: string; + let secondBridgeCalldata: BytesLike; + if (tx.bridgeAddress) { + secondBridgeAddress = tx.bridgeAddress; + secondBridgeCalldata = await getERC20DefaultBridgeData( + transaction.token, + this._providerL1() + ); } else { - const refundRecipient = tx.refundRecipient ?? ethers.ZeroAddress; - const args: [ - Address, - Address, - BigNumberish, - BigNumberish, - BigNumberish, - Address, - ] = [ - to, - token, - amount, - tx.l2GasLimit, - tx.gasPerPubdataByte, - refundRecipient, - ]; + secondBridgeAddress = await ( + await this.getL1BridgeContracts() + ).shared.getAddress(); + secondBridgeCalldata = ethers.AbiCoder.defaultAbiCoder().encode( + ['address', 'uint256', 'address'], + [token, amount, to] + ); + } - overrides.value ??= baseCost + BigInt(operatorTip); - await checkBaseCost(baseCost, overrides.value); - overrides.from ??= await this.getAddress(); + return await bridgehub.requestL2TransactionTwoBridges.populateTransaction( + { + chainId, + mintValue, + l2Value: 0, + l2GasLimit, + l2GasPerPubdataByteLimit: gasPerPubdataByte, + refundRecipient: refundRecipient ?? ethers.ZeroAddress, + secondBridgeAddress, + secondBridgeValue: 0, + secondBridgeCalldata, + }, + overrides + ); + } - let l2WethToken = ethers.ZeroAddress; - try { - l2WethToken = await bridgeContracts.weth.l2TokenAddress(tx.token); - } catch (e) { - // skip - } + async _getDepositETHOnETHBasedChainTx(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }) { + // Call the BridgeHub directly, like it's done with the DiamondProxy. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + + const tx = await this._getDepositTxWithDefaults(transaction); + const { + operatorTip, + amount, + overrides, + l2GasLimit, + gasPerPubdataByte, + to, + } = tx; + + const gasPriceForEstimation = + overrides.maxFeePerGas || overrides.gasPrice; + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + l2GasLimit, + gasPerPubdataByte + ); + + overrides.value ??= baseCost + BigInt(operatorTip) + BigInt(amount); + + return { + contractAddress: to, + calldata: '0x', + mintValue: overrides.value, + l2Value: amount, + ...tx, + }; + } - const bridge = - l2WethToken !== ethers.ZeroAddress - ? bridgeContracts.weth - : bridgeContracts.erc20; + // Creates a shallow copy of a transaction and populates missing fields with defaults. + async _getDepositTxWithDefaults(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }): Promise<{ + token: Address; + amount: BigNumberish; + to: Address; + operatorTip: BigNumberish; + bridgeAddress?: Address; + l2GasLimit: BigNumberish; + gasPerPubdataByte: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides: ethers.Overrides; + }> { + const {...tx} = transaction; + tx.to = tx.to ?? (await this.getAddress()); + tx.operatorTip ??= 0; + tx.overrides ??= {}; + tx.overrides.from = await this.getAddress(); + tx.gasPerPubdataByte ??= REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; + tx.l2GasLimit ??= await this._getL2GasLimit(tx); + await insertGasPrice(this._providerL1(), tx.overrides); - return await bridge.deposit.populateTransaction(...args, overrides); + return tx as { + token: Address; + amount: BigNumberish; + to: Address; + operatorTip: BigNumberish; + bridgeAddress?: Address; + l2GasLimit: BigNumberish; + gasPerPubdataByte: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides: ethers.Overrides; + }; + } + + // Default behaviour for calculating l2GasLimit of deposit transaction. + async _getL2GasLimit(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }): Promise { + if (transaction.bridgeAddress) { + return await this._getL2GasLimitFromCustomBridge(transaction); + } else { + return await estimateDefaultBridgeDepositL2Gas( + this._providerL1(), + this._providerL2(), + transaction.token, + transaction.amount, + transaction.to!, + await this.getAddress(), + transaction.gasPerPubdataByte + ); } } + // Calculates the l2GasLimit of deposit transaction using custom bridge. + async _getL2GasLimitFromCustomBridge(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }): Promise { + const customBridgeData = + transaction.customBridgeData ?? + (await getERC20DefaultBridgeData( + transaction.token, + this._providerL1() + )); + const bridge = IL1Bridge__factory.connect( + transaction.bridgeAddress!, + this._signerL1() + ); + const chainId = (await this._providerL2().getNetwork()) + .chainId as BigNumberish; + const l2Address = await bridge.l2BridgeAddress(chainId); + return await estimateCustomBridgeDepositL2Gas( + this._providerL2(), + transaction.bridgeAddress!, + l2Address, + transaction.token, + transaction.amount, + transaction.to!, + customBridgeData, + await this.getAddress(), + transaction.gasPerPubdataByte + ); + } + /** * Retrieves the full needed ETH fee for the deposit. Returns the L1 fee and the L2 fee {@link FullDepositFee}. * @@ -561,93 +1212,74 @@ export function AdapterL1>(Base: TBase) { gasPerPubdataByte?: BigNumberish; overrides?: ethers.Overrides; }): Promise { + if (transaction.token === LEGACY_ETH_ADDRESS) { + transaction.token = ETH_ADDRESS_IN_CONTRACTS; + } // It is assumed that the L2 fee for the transaction does not depend on its value. const dummyAmount = 1n; + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const isETHBasedChain = baseTokenAddress === ETH_ADDRESS_IN_CONTRACTS; - const {...tx} = transaction; - const zksyncContract = await this.getMainContract(); + const tx = await this._getDepositTxWithDefaults({ + ...transaction, + amount: dummyAmount, + }); - tx.overrides ??= {}; - await insertGasPrice(this._providerL1(), tx.overrides); - const gasPriceForMessages = + const gasPriceForEstimation = tx.overrides.maxFeePerGas || tx.overrides.gasPrice; - - tx.to ??= await this.getAddress(); - tx.gasPerPubdataByte ??= REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; - - let l2GasLimit: bigint; - if (tx.bridgeAddress) { - const bridgeContracts = await this.getL1BridgeContracts(); - const customBridgeData = - tx.customBridgeData ?? - (await bridgeContracts.weth.getAddress()) === tx.bridgeAddress - ? '0x' - : await getERC20DefaultBridgeData(tx.token, this._providerL1()); - const bridge = IL1Bridge__factory.connect( - tx.bridgeAddress, - this._signerL1() - ); - const l2Address = await bridge.l2Bridge(); - l2GasLimit = await estimateCustomBridgeDepositL2Gas( - this._providerL2(), - tx.bridgeAddress, - l2Address, - tx.token, - dummyAmount, - tx.to, - customBridgeData, - await this.getAddress(), - tx.gasPerPubdataByte - ); - } else { - l2GasLimit = await estimateDefaultBridgeDepositL2Gas( - this._providerL1(), - this._providerL2(), - tx.token, - dummyAmount, - tx.to, - await this.getAddress(), - tx.gasPerPubdataByte - ); - } - - const baseCost = await zksyncContract.l2TransactionBaseCost( - gasPriceForMessages!, - l2GasLimit, + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + tx.l2GasLimit, tx.gasPerPubdataByte ); - const selfBalanceETH = await this.getBalanceL1(); - - // We could zero in, because the final fee will anyway be bigger than - if (baseCost >= selfBalanceETH + dummyAmount) { - const recommendedETHBalance = - BigInt( + if (isETHBasedChain) { + // To ensure that L1 gas estimation succeeds when using estimateGasDeposit, + // the account needs to have a sufficient ETH balance. + const selfBalanceETH = await this.getBalanceL1(); + if (baseCost >= selfBalanceETH + dummyAmount) { + const recommendedL1GasLimit = tx.token === ETH_ADDRESS ? L1_RECOMMENDED_MIN_ETH_DEPOSIT_GAS_LIMIT - : L1_RECOMMENDED_MIN_ERC20_DEPOSIT_GAS_LIMIT - ) * - BigInt(gasPriceForMessages!) + - baseCost; - const formattedRecommendedBalance = ethers.formatEther( - recommendedETHBalance - ); - throw new Error( - `Not enough balance for deposit! Under the provided gas price, the recommended balance to perform a deposit is ${formattedRecommendedBalance} ETH.` - ); - } - - // For ETH token the value that the user passes to the estimation is the one which has the - // value for the L2 commission subtracted. - let amountForEstimate: bigint; - if (isETH(tx.token)) { - amountForEstimate = dummyAmount; - } else { - amountForEstimate = dummyAmount; - - if ((await this.getAllowanceL1(tx.token)) < amountForEstimate) { + : L1_RECOMMENDED_MIN_ERC20_DEPOSIT_GAS_LIMIT; + const recommendedETHBalance = + BigInt(recommendedL1GasLimit) * BigInt(gasPriceForEstimation!) + + baseCost; + const formattedRecommendedBalance = ethers.formatEther( + recommendedETHBalance + ); + throw new Error( + `Not enough balance for deposit! Under the provided gas price, the recommended balance to perform a deposit is ${formattedRecommendedBalance} ETH` + ); + } + // In case of token deposit, a sufficient token allowance is also required. + if ( + tx.token !== ETH_ADDRESS_IN_CONTRACTS && + (await this.getAllowanceL1(tx.token)) < dummyAmount + ) { throw new Error('Not enough allowance to cover the deposit!'); } + } else { + const mintValue = baseCost + BigInt(tx.operatorTip); + if ((await this.getAllowanceL1(baseTokenAddress)) < mintValue) { + throw new Error( + 'Not enough base token allowance to cover the deposit!' + ); + } + if ( + tx.token === ETH_ADDRESS_IN_CONTRACTS || + tx.token === baseTokenAddress + ) { + tx.overrides.value ??= tx.amount; + } else { + tx.overrides.value ??= 0; + if ((await this.getAllowanceL1(tx.token)) < dummyAmount) { + throw new Error('Not enough token allowance to cover the deposit!'); + } + } } // Deleting the explicit gas limits in the fee estimation @@ -660,15 +1292,15 @@ export function AdapterL1>(Base: TBase) { const l1GasLimit = await this.estimateGasDeposit({ ...tx, - amount: amountForEstimate, + amount: dummyAmount, overrides: estimationOverrides, - l2GasLimit, + l2GasLimit: tx.l2GasLimit, }); const fullCost: FullDepositFee = { baseCost, l1GasLimit, - l2GasLimit, + l2GasLimit: BigInt(tx.l2GasLimit), }; if (tx.overrides.gasPrice) { @@ -683,6 +1315,18 @@ export function AdapterL1>(Base: TBase) { return fullCost; } + /** + * Returns the transaction confirmation data that is part of `L2->L1` message. + * + * @param txHash The hash of the L2 transaction where the message was initiated. + * @param [index=0] In case there were multiple transactions in one message, you may pass an index of the + * transaction which confirmation data should be fetched. + * @throws {Error} If log proof can not be found. + */ + async getPriorityOpConfirmation(txHash: string, index = 0) { + return this._providerL2().getPriorityOpConfirmation(txHash, index); + } + async _getWithdrawalLog(withdrawalHash: BytesLike, index = 0) { const hash = ethers.hexlify(withdrawalHash); const receipt = await this._providerL2().getTransactionReceipt(hash); @@ -770,60 +1414,19 @@ export function AdapterL1>(Base: TBase) { index = 0, overrides?: ethers.Overrides ): Promise { - const { - l1BatchNumber, - l2MessageIndex, - l2TxNumberInBlock, - message, - sender, - proof, - } = await this.finalizeWithdrawalParams(withdrawalHash, index); + const {l1BatchNumber, l2MessageIndex, l2TxNumberInBlock, message, proof} = + await this.finalizeWithdrawalParams(withdrawalHash, index); - if (isETH(sender)) { - const withdrawTo = ethers.dataSlice(message, 4, 24); - const l1Bridges = await this.getL1BridgeContracts(); - // If the destination address matches the address of the L1 WETH contract, - // the withdrawal request is processed through the WETH bridge. - if ( - withdrawTo.toLowerCase() === - (await l1Bridges.weth.getAddress()).toLowerCase() - ) { - return await l1Bridges.weth.finalizeWithdrawal( - l1BatchNumber!, - l2MessageIndex, - l2TxNumberInBlock!, - message, - proof, - overrides ?? {} - ); - } - - const contractAddress = - await this._providerL2().getMainContractAddress(); - const zksync = IZkSync__factory.connect( - contractAddress, - this._signerL1() - ); - - return await zksync.finalizeEthWithdrawal( - l1BatchNumber!, - l2MessageIndex!, - l2TxNumberInBlock!, - message, - proof, - overrides ?? {} - ); - } - - const l2Bridge = IL2Bridge__factory.connect(sender, this._providerL2()); - const l1Bridge = IL1Bridge__factory.connect( - await l2Bridge.l1Bridge(), + const bridgehub = await this.getBridgehubContract(); + const l1SharedBridge = IL1SharedBridge__factory.connect( + await bridgehub.sharedBridge(), this._signerL1() ); - return await l1Bridge.finalizeWithdrawal( - l1BatchNumber!, - l2MessageIndex!, - l2TxNumberInBlock!, + return await l1SharedBridge.finalizeWithdrawal( + (await this._providerL2().getNetwork()).chainId as BigNumberish, + l1BatchNumber as BigNumberish, + l2MessageIndex as BigNumberish, + l2TxNumberInBlock as BigNumberish, message, proof, overrides ?? {} @@ -859,27 +1462,25 @@ export function AdapterL1>(Base: TBase) { throw new Error('Log proof not found!'); } - if (isETH(sender)) { - const contractAddress = - await this._providerL2().getMainContractAddress(); - const zksync = IZkSync__factory.connect( - contractAddress, - this._signerL1() - ); + const chainId = (await this._providerL2().getNetwork()).chainId; - return await zksync.isEthWithdrawalFinalized( - log.l1BatchNumber!, - proof.id + let l1Bridge: IL1SharedBridge; + + if (await this._providerL2().isBaseToken(sender)) { + l1Bridge = (await this.getL1BridgeContracts()).shared; + } else { + const l2Bridge = IL2Bridge__factory.connect(sender, this._providerL2()); + l1Bridge = IL1SharedBridge__factory.connect( + await l2Bridge.l1Bridge(), + this._providerL1() ); } - const l2Bridge = IL2Bridge__factory.connect(sender, this._providerL2()); - const l1Bridge = IL1Bridge__factory.connect( - await l2Bridge.l1Bridge(), - this._providerL1() + return await l1Bridge.isWithdrawalFinalized( + chainId, + log.l1BatchNumber!, + proof.id ); - - return await l1Bridge.isWithdrawalFinalized(log.l1BatchNumber!, proof.id); } /** @@ -920,7 +1521,7 @@ export function AdapterL1>(Base: TBase) { throw new Error('L2 bridge address not found!'); } - const l1Bridge = IL1Bridge__factory.connect( + const l1Bridge = IL1SharedBridge__factory.connect( l1BridgeAddress, this._signerL1() ); @@ -942,8 +1543,10 @@ export function AdapterL1>(Base: TBase) { throw new Error('Log proof not found!'); } return await l1Bridge.claimFailedDeposit( + (await this._providerL2().getNetwork()).chainId as BigNumberish, calldata['_l1Sender'], calldata['_l1Token'], + calldata['_amount'], depositHash, receipt.l1BatchNumber!, proof.id, @@ -960,6 +1563,7 @@ export function AdapterL1>(Base: TBase) { * @param transaction.contractAddress The L2 contract to be called. * @param transaction.calldata The input of the L2 transaction. * @param [transaction.l2GasLimit] Maximum amount of L2 gas that transaction can consume during execution on L2. + * @param [transaction.mintValue] The amount of base token that needs to be minted on non-ETH-based L2. * @param [transaction.l2Value] `msg.value` of L2 transaction. * @param [transaction.factoryDeps] An array of L2 bytecodes that will be marked as known on L2. * @param [transaction.operatorTip] (currently not used) If the ETH value passed with the transaction is not @@ -975,6 +1579,7 @@ export function AdapterL1>(Base: TBase) { contractAddress: Address; calldata: string; l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: ethers.BytesLike[]; operatorTip?: BigNumberish; @@ -995,6 +1600,7 @@ export function AdapterL1>(Base: TBase) { * @param transaction.contractAddress The L2 contract to be called. * @param transaction.calldata The input of the L2 transaction. * @param [transaction.l2GasLimit] Maximum amount of L2 gas that transaction can consume during execution on L2. + * @param [transaction.mintValue] The amount of base token that needs to be minted on non-ETH-based L2. * @param [transaction.l2Value] `msg.value` of L2 transaction. * @param [transaction.factoryDeps] An array of L2 bytecodes that will be marked as known on L2. * @param [transaction.operatorTip] (currently not used) If the ETH value passed with the transaction is not @@ -1009,6 +1615,7 @@ export function AdapterL1>(Base: TBase) { contractAddress: Address; calldata: string; l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: ethers.BytesLike[]; operatorTip?: BigNumberish; @@ -1025,6 +1632,61 @@ export function AdapterL1>(Base: TBase) { return this._providerL1().estimateGas(requestExecuteTx); } + /** + * Returns the parameters for the approval token transaction based on the request execute transaction. + * Existing allowance for the bridge is not checked; allowance is calculated solely based on the specified transaction. + * + * @param transaction The request execute transaction on which approval parameters are calculated. + */ + async getRequestExecuteAllowanceParams(transaction: { + contractAddress: Address; + calldata: string; + l2GasLimit?: BigNumberish; + l2Value?: BigNumberish; + factoryDeps?: ethers.BytesLike[]; + operatorTip?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }): Promise<{token: Address; allowance: BigNumberish}> { + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const isETHBaseToken = + (await bridgehub.baseToken(chainId)) === ETH_ADDRESS_IN_CONTRACTS; + + if (isETHBaseToken) { + throw new Error('Could not estimate mint value on ETH-based chain!'); + } + + const {...tx} = transaction; + tx.l2Value ??= 0n; + tx.operatorTip ??= 0n; + tx.factoryDeps ??= []; + tx.overrides ??= {}; + tx.gasPerPubdataByte ??= REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; + tx.refundRecipient ??= await this.getAddress(); + tx.l2GasLimit ??= + await this._providerL2().estimateL1ToL2Execute(transaction); + + const {l2Value, l2GasLimit, operatorTip, overrides, gasPerPubdataByte} = + tx; + + await insertGasPrice(this._providerL1(), overrides); + const gasPriceForEstimation = + overrides.maxFeePerGas || overrides.gasPrice; + + const baseCost = await this.getBaseCost({ + gasPrice: gasPriceForEstimation!, + gasPerPubdataByte, + gasLimit: l2GasLimit, + }); + + return { + token: await this.getBaseToken(), + allowance: baseCost + BigInt(operatorTip) + BigInt(l2Value), + }; + } + /** * Returns a populated request execute transaction. * @@ -1032,6 +1694,7 @@ export function AdapterL1>(Base: TBase) { * @param transaction.contractAddress The L2 contract to be called. * @param transaction.calldata The input of the L2 transaction. * @param [transaction.l2GasLimit] Maximum amount of L2 gas that transaction can consume during execution on L2. + * @param [transaction.mintValue] The amount of base token that needs to be minted on non-ETH-based L2. * @param [transaction.l2Value] `msg.value` of L2 transaction. * @param [transaction.factoryDeps] An array of L2 bytecodes that will be marked as known on L2. * @param [transaction.operatorTip] (currently not used) If the ETH value passed with the transaction is not @@ -1046,6 +1709,7 @@ export function AdapterL1>(Base: TBase) { contractAddress: Address; calldata: string; l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: ethers.BytesLike[]; operatorTip?: BigNumberish; @@ -1053,10 +1717,14 @@ export function AdapterL1>(Base: TBase) { refundRecipient?: Address; overrides?: ethers.Overrides; }): Promise { - const zksyncContract = await this.getMainContract(); + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const isETHBaseToken = + (await bridgehub.baseToken(chainId)) === ETH_ADDRESS_IN_CONTRACTS; const {...tx} = transaction; tx.l2Value ??= 0; + tx.mintValue ??= 0; tx.operatorTip ??= 0; tx.factoryDeps ??= []; tx.overrides ??= {}; @@ -1068,6 +1736,7 @@ export function AdapterL1>(Base: TBase) { const { contractAddress, + mintValue, l2Value, calldata, l2GasLimit, @@ -1088,18 +1757,30 @@ export function AdapterL1>(Base: TBase) { gasLimit: l2GasLimit, }); - overrides.value ??= baseCost + BigInt(operatorTip) + BigInt(l2Value); - - await checkBaseCost(baseCost, overrides.value); + const l2Costs = baseCost + BigInt(operatorTip) + BigInt(l2Value); + let providedValue = isETHBaseToken ? overrides.value : mintValue; + if ( + providedValue === undefined || + providedValue === null || + BigInt(providedValue) === 0n + ) { + providedValue = l2Costs; + if (isETHBaseToken) overrides.value = providedValue; + } + await checkBaseCost(baseCost, providedValue); - return await zksyncContract.requestL2Transaction.populateTransaction( - contractAddress, - l2Value, - calldata, - l2GasLimit, - REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, - factoryDeps, - refundRecipient, + return await bridgehub.requestL2TransactionDirect.populateTransaction( + { + chainId, + mintValue: providedValue, + l2Contract: contractAddress, + l2Value: l2Value, + l2Calldata: calldata, + l2GasLimit: l2GasLimit, + l2GasPerPubdataByteLimit: REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, + factoryDeps: factoryDeps, + refundRecipient: refundRecipient, + }, overrides ); } @@ -1161,11 +1842,13 @@ export function AdapterL2>(Base: TBase) { /** * Returns L2 bridge contracts. */ - async getL2BridgeContracts(): Promise<{erc20: IL2Bridge; weth: IL2Bridge}> { + async getL2BridgeContracts(): Promise<{shared: IL2Bridge}> { const addresses = await this._providerL2().getDefaultBridgeAddresses(); return { - erc20: IL2Bridge__factory.connect(addresses.erc20L2!, this._signerL2()), - weth: IL2Bridge__factory.connect(addresses.wethL2!, this._signerL2()), + shared: IL2Bridge__factory.connect( + addresses.sharedL2, + this._signerL2() + ), }; } diff --git a/src/provider.ts b/src/provider.ts index bdf5461c..f289bddd 100644 --- a/src/provider.ts +++ b/src/provider.ts @@ -48,11 +48,13 @@ import { getL2HashFromPriorityOp, CONTRACT_DEPLOYER_ADDRESS, CONTRACT_DEPLOYER, - ETH_ADDRESS, sleep, - L2_ETH_TOKEN_ADDRESS, EIP712_TX_TYPE, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, + BOOTLOADER_FORMAL_ADDRESS, + ETH_ADDRESS_IN_CONTRACTS, + L2_BASE_TOKEN_ADDRESS, + LEGACY_ETH_ADDRESS, } from './utils'; import {Signer} from './signer'; @@ -86,11 +88,12 @@ export function JsonRpcApiProvider< * Returns the addresses of the main contract and default zkSync Era bridge contracts on both L1 and L2. */ contractAddresses(): { + bridgehubContract?: Address; mainContract?: Address; erc20BridgeL1?: Address; - erc20BridgeL2?: Address; - wethBridgeL1?: Address; - wethBridgeL2?: Address; + sharedBridgeL1?: Address; + sharedBridgeL2?: Address; + baseToken?: Address; } { throw new Error('Must be implemented by the derived class!'); } @@ -194,7 +197,7 @@ export function JsonRpcApiProvider< blockTag?: BlockTag, tokenAddress?: Address ): Promise { - if (!tokenAddress || isETH(tokenAddress)) { + if (!tokenAddress || (await this.isBaseToken(tokenAddress))) { return await super.getBalance(address, blockTag); } else { try { @@ -215,29 +218,21 @@ export function JsonRpcApiProvider< * @param token The address of the token on L1. */ async l2TokenAddress(token: Address): Promise { - if (token === ETH_ADDRESS) { - return ETH_ADDRESS; - } else { - const bridgeAddresses = await this.getDefaultBridgeAddresses(); - const l2WethBridge = IL2Bridge__factory.connect( - bridgeAddresses.wethL2!, - this - ); - try { - const l2WethToken = await l2WethBridge.l2TokenAddress(token); - if (l2WethToken !== ethers.ZeroAddress) { - return l2WethToken; - } - } catch (e) { - // skip - } + if (token === LEGACY_ETH_ADDRESS) { + token = ETH_ADDRESS_IN_CONTRACTS; + } - const erc20Bridge = IL2Bridge__factory.connect( - bridgeAddresses.erc20L2!, - this - ); - return await erc20Bridge.l2TokenAddress(token); + const baseToken = await this.getBaseTokenContractAddress(); + if (token.toLowerCase() === baseToken.toLowerCase()) { + return L2_BASE_TOKEN_ADDRESS; } + + const bridgeAddresses = await this.getDefaultBridgeAddresses(); + const l2SharedBridge = IL2Bridge__factory.connect( + bridgeAddresses.sharedL2, + this + ); + return await l2SharedBridge.l2TokenAddress(token); } /** @@ -249,28 +244,17 @@ export function JsonRpcApiProvider< * @param token The address of the token on L2. */ async l1TokenAddress(token: Address): Promise { - if (token === ETH_ADDRESS) { - return ETH_ADDRESS; - } else { - const bridgeAddresses = await this.getDefaultBridgeAddresses(); - const l2WethBridge = IL2Bridge__factory.connect( - bridgeAddresses.wethL2!, - this - ); - try { - const l1WethToken = await l2WethBridge.l1TokenAddress(token); - if (l1WethToken !== ethers.ZeroAddress) { - return l1WethToken; - } - } catch (e) { - // skip - } - const erc20Bridge = IL2Bridge__factory.connect( - bridgeAddresses.erc20L2!, - this - ); - return await erc20Bridge.l1TokenAddress(token); + if (token === LEGACY_ETH_ADDRESS) { + return LEGACY_ETH_ADDRESS; } + + const bridgeAddresses = await this.getDefaultBridgeAddresses(); + + const sharedBridge = IL2Bridge__factory.connect( + bridgeAddresses.sharedL2, + this + ); + return await sharedBridge.l1TokenAddress(token); } /** @@ -340,6 +324,21 @@ export function JsonRpcApiProvider< return [parseInt(range[0], 16), parseInt(range[1], 16)]; } + /** + * Returns the Bridgehub smart contract address. + * + * Calls the {@link https://docs.zksync.io/build/api.html#zks-getbridgehubcontract zks_getBridgehubContract} JSON-RPC method. + */ + async getBridgehubContractAddress(): Promise
{ + if (!this.contractAddresses().bridgehubContract) { + this.contractAddresses().bridgehubContract = await this.send( + 'zks_getBridgehubContract', + [] + ); + } + return this.contractAddresses().bridgehubContract!; + } + /** * Returns the main zkSync Era smart contract address. * @@ -355,6 +354,38 @@ export function JsonRpcApiProvider< return this.contractAddresses().mainContract!; } + /** + * Returns the L1 base token address. + */ + async getBaseTokenContractAddress(): Promise
{ + if (!this.contractAddresses().baseToken) { + this.contractAddresses().baseToken = await this.send( + 'zks_getBaseTokenL1Address', + [] + ); + } + return ethers.getAddress(this.contractAddresses().baseToken!); + } + + /** + * Returns whether the chain is ETH-based. + */ + async isEthBasedChain(): Promise { + return ( + (await this.getBaseTokenContractAddress()) === ETH_ADDRESS_IN_CONTRACTS + ); + } + + /** + * Returns whether the `token` is the base token. + */ + async isBaseToken(token: Address): Promise { + return ( + token === (await this.getBaseTokenContractAddress()) || + token === L2_BASE_TOKEN_ADDRESS + ); + } + /** * Returns the testnet {@link https://docs.zksync.io/build/developer-reference/account-abstraction.html#paymasters paymaster address} * if available, or `null`. @@ -373,28 +404,27 @@ export function JsonRpcApiProvider< * Calls the {@link https://docs.zksync.io/build/api.html#zks-getbridgecontracts zks_getBridgeContracts} JSON-RPC method. */ async getDefaultBridgeAddresses(): Promise<{ - erc20L1: string | undefined; - erc20L2: string | undefined; - wethL1: string | undefined; - wethL2: string | undefined; + erc20L1: string; + sharedL1: string; + sharedL2: string; }> { if (!this.contractAddresses().erc20BridgeL1) { const addresses: { l1Erc20DefaultBridge: string; - l2Erc20DefaultBridge: string; - l1WethBridge: string; - l2WethBridge: string; + l1SharedDefaultBridge: string; + l2SharedDefaultBridge: string; } = await this.send('zks_getBridgeContracts', []); + this.contractAddresses().erc20BridgeL1 = addresses.l1Erc20DefaultBridge; - this.contractAddresses().erc20BridgeL2 = addresses.l2Erc20DefaultBridge; - this.contractAddresses().wethBridgeL1 = addresses.l1WethBridge; - this.contractAddresses().wethBridgeL2 = addresses.l2WethBridge; + this.contractAddresses().sharedBridgeL1 = + addresses.l1SharedDefaultBridge; + this.contractAddresses().sharedBridgeL2 = + addresses.l2SharedDefaultBridge; } return { - erc20L1: this.contractAddresses().erc20BridgeL1, - erc20L2: this.contractAddresses().erc20BridgeL2, - wethL1: this.contractAddresses().wethBridgeL1, - wethL2: this.contractAddresses().wethBridgeL2, + erc20L1: this.contractAddresses().erc20BridgeL1!, + sharedL1: this.contractAddresses().sharedBridgeL1!, + sharedL2: this.contractAddresses().sharedBridgeL2!, }; } @@ -532,6 +562,9 @@ export function JsonRpcApiProvider< overrides?: ethers.Overrides; }): Promise { const {...tx} = transaction; + if (tx.token === LEGACY_ETH_ADDRESS) { + tx.token = ETH_ADDRESS_IN_CONTRACTS; + } if ( (tx.to === null || tx.to === undefined) && @@ -558,7 +591,7 @@ export function JsonRpcApiProvider< } const ethL2Token = IEthToken__factory.connect( - L2_ETH_TOKEN_ADDRESS, + L2_BASE_TOKEN_ADDRESS, this ); const populatedTx = await ethL2Token.withdraw.populateTransaction( @@ -578,20 +611,7 @@ export function JsonRpcApiProvider< if (!tx.bridgeAddress) { const bridgeAddresses = await this.getDefaultBridgeAddresses(); - const l2WethBridge = IL2Bridge__factory.connect( - bridgeAddresses.wethL2!, - this - ); - let l1WethToken = ethers.ZeroAddress; - try { - l1WethToken = await l2WethBridge.l1TokenAddress(tx.token); - } catch (e) { - // skip - } - tx.bridgeAddress = - l1WethToken !== ethers.ZeroAddress - ? bridgeAddresses.wethL2 - : bridgeAddresses.erc20L2; + tx.bridgeAddress = bridgeAddresses.sharedL2; } const bridge = IL2Bridge__factory.connect(tx.bridgeAddress!, this); @@ -659,7 +679,11 @@ export function JsonRpcApiProvider< tx.overrides ??= {}; tx.overrides.from ??= tx.from; - if (!tx.token || tx.token === ETH_ADDRESS) { + if ( + !tx.token || + tx.token === LEGACY_ETH_ADDRESS || + (await this.isBaseToken(tx.token)) + ) { if (tx.paymasterParams) { return { ...tx.overrides, @@ -858,6 +882,51 @@ export function JsonRpcApiProvider< return l2Response; } + async _getPriorityOpConfirmationL2ToL1Log(txHash: string, index = 0) { + const hash = ethers.hexlify(txHash); + const receipt = await this.getTransactionReceipt(hash); + const messages = Array.from(receipt.l2ToL1Logs.entries()).filter( + ([, log]) => log.sender === BOOTLOADER_FORMAL_ADDRESS + ); + const [l2ToL1LogIndex, l2ToL1Log] = messages[index]; + + return { + l2ToL1LogIndex, + l2ToL1Log, + l1BatchTxId: receipt.l1BatchTxIndex, + }; + } + + /** + * Returns the transaction confirmation data that is part of `L2->L1` message. + * + * @param txHash The hash of the L2 transaction where the message was initiated. + * @param [index=0] In case there were multiple transactions in one message, you may pass an index of the + * transaction which confirmation data should be fetched. + * @throws {Error} If log proof can not be found. + * + * @example + * + * import { Provider, types, utils } from "zksync-ethers"; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * // Any L2 -> L1 transaction can be used. + * // In this case, withdrawal transaction is used. + * const tx = "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e"; + * console.log(`Confirmation data: ${utils.toJSON(await provider.getPriorityOpConfirmation(tx, 0))}`); + */ + async getPriorityOpConfirmation(txHash: string, index = 0) { + const {l2ToL1LogIndex, l2ToL1Log, l1BatchTxId} = + await this._getPriorityOpConfirmationL2ToL1Log(txHash, index); + const proof = await this.getLogProof(txHash, l2ToL1LogIndex); + return { + l1BatchNumber: l2ToL1Log.l1BatchNumber, + l2MessageIndex: proof!.id, + l2TxNumberInBlock: l1BatchTxId, + proof: proof!.proof, + }; + } + /** * Returns the version of the supported account abstraction and nonce ordering from a given contract address. * @@ -1269,10 +1338,9 @@ export class Provider extends JsonRpcApiProvider(ethers.JsonRpcProvider) { * console.log(`Default bridges: ${utils.toJSON(await provider.getDefaultBridgeAddresses())}`); */ override async getDefaultBridgeAddresses(): Promise<{ - erc20L1: string | undefined; - erc20L2: string | undefined; - wethL1: string | undefined; - wethL2: string | undefined; + erc20L1: string; + sharedL1: string; + sharedL2: string; }> { return super.getDefaultBridgeAddresses(); } diff --git a/src/signer.ts b/src/signer.ts index 413e1a24..09c181a5 100644 --- a/src/signer.ts +++ b/src/signer.ts @@ -26,7 +26,13 @@ import { TransactionResponse, } from './types'; import {AdapterL1, AdapterL2} from './adapters'; -import {IL1Bridge, IL2Bridge, IZkSync} from './typechain'; +import { + IBridgehub, + IL1ERC20Bridge, + IL1SharedBridge, + IL2Bridge, + IZkSyncStateTransition, +} from './typechain'; /** * All typed data conforming to the EIP712 standard within zkSync Era. @@ -275,17 +281,14 @@ export class Signer extends AdapterL2(ethers.JsonRpcSigner) { * * const l2BridgeContracts = await signer.getL2BridgeContracts(); */ - override async getL2BridgeContracts(): Promise<{ - erc20: IL2Bridge; - weth: IL2Bridge; - }> { + override async getL2BridgeContracts(): Promise<{shared: IL2Bridge}> { return super.getL2BridgeContracts(); } /** * @inheritDoc * - * @example Withdraw ETH. + * @example Withdraw token. * * import { BrowserProvider, Provider, types } from "zksync-ethers"; * import { ethers } from "ethers"; @@ -303,7 +306,7 @@ export class Signer extends AdapterL2(ethers.JsonRpcSigner) { * amount: 10_000_000, * }); * - * @example Withdraw ETH using paymaster to facilitate fee payment with an ERC20 token. + * @example Withdraw token using paymaster to facilitate fee payment with an ERC20 token. * * import { BrowserProvider, Provider, types } from "zksync-ethers"; * @@ -318,7 +321,7 @@ export class Signer extends AdapterL2(ethers.JsonRpcSigner) { * ); * * const tokenL2 = "0x6a4Fb925583F7D4dF82de62d98107468aE846FD1"; - * const tx = await wallet.withdraw({ + * const tx = await signer.withdraw({ * token: tokenL2, * amount: 10_000_000n, * paymasterParams: utils.getPaymasterParams(paymaster, { @@ -553,12 +556,31 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { * ); * * const mainContract = await signer.getMainContract(); - * console.log(mainContract.address); */ - override async getMainContract(): Promise { + override async getMainContract(): Promise { return super.getMainContract(); } + /** + * @inheritDoc + * + * @example + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const bridgehub = await signer.getBridgehubContract(); + */ + override async getBridgehubContract(): Promise { + return super.getBridgehubContract(); + } + /** * @inheritDoc * @@ -576,8 +598,8 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { * const l1BridgeContracts = await signer.getL1BridgeContracts(); */ override async getL1BridgeContracts(): Promise<{ - erc20: IL1Bridge; - weth: IL1Bridge; + erc20: IL1ERC20Bridge; + shared: IL1SharedBridge; }> { return super.getL1BridgeContracts(); } @@ -721,7 +743,133 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { /** * @inheritDoc * - * @example Deposit ETH + * @example + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * console.log(`Base token: ${await signer.getBaseToken()}`); + */ + override async getBaseToken(): Promise { + return super.getBaseToken(); + } + + /** + * @inheritDoc + * + * @example + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * console.log(`Is ETH-based chain: ${await signer.isETHBasedChain()}`); + */ + override async isETHBasedChain(): Promise { + return super.isETHBasedChain(); + } + + /** + * @inheritDoc + * + * @example Get allowance parameters for depositing ETH on non-ETH-based chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const token = utils.LEGACY_ETH_ADDRESS; + * const amount = 5; + * const approveParams = await signer.getDepositAllowanceParams(token, amount); + * await ( + * await signer.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * @example Get allowance parameters for depositing base token on non-ETH-based chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const token = await signer.getBaseToken(); + * const amount = 5; + * const approveParams = await signer.getDepositAllowanceParams(token, amount); + * await ( + * await signer.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * @example Get allowance parameters for depositing non-base token on non-ETH-based chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const token = ""; + * const amount = 5; + * const approveParams = await signer.getDepositAllowanceParams(token, amount); + * + * await ( + * await signer.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * await ( + * await signer.approveERC20( + * approveParams[1].token, + * approveParams[1].allowance + * ) + * ).wait(); + */ + override async getDepositAllowanceParams( + token: Address, + amount: BigNumberish + ): Promise< + { + token: Address; + allowance: BigNumberish; + }[] + > { + return super.getDepositAllowanceParams(token, amount); + } + + /** + * @inheritDoc + * + * @example Deposit ETH on ETH-based chain. * * import { Provider, L1Signer, types } from "zksync-ethers"; * import { ethers } from "ethers"; @@ -737,7 +885,7 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { * amount: 10_000_000n, * }); * - * @example Deposit token + * @example Deposit token on ETH-based chain. * * import { Provider, L1Signer, types } from "zksync-ethers"; * import { ethers } from "ethers"; @@ -754,6 +902,59 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { * amount: 10_000_000n, * approveERC20: true, * }); + * + * @example Deposit ETH on non-ETH-chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * await signer.deposit({ + * token: utils.ETH_ADDRESS, + * amount: 10_000_000, + * approveBaseERC20: true, + * }); + * + * @example Deposit base token on non-ETH-based chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * await signer.deposit({ + * token: await signer.getBaseToken(), + * amount: 10_000_000, + * approveERC20: true, // or approveBaseERC20: true + * }); + * + * @example Deposit non-base token on non-ETH-based chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const tokenL1 = "0x56E69Fa1BB0d1402c89E3A4E3417882DeA6B14Be"; + * await signer.deposit({ + * token: tokenL1, + * amount: 10_000_000, + * approveERC20: true, + * approveBaseERC20: true, + * }); */ override async deposit(transaction: { token: Address; @@ -972,6 +1173,48 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { return super.claimFailedDeposit(depositHash, overrides); } + /** + * @inheritDoc + * + * @example + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const tx = { + * contractAddress: await signer.getAddress(), + * calldata: '0x', + * l2Value: 7_000_000_000, + * }; + * + * const approveParams = await signer.getRequestExecuteAllowanceParams(tx); + * await ( + * await signer.approveERC20( + * approveParams.token, + * approveParams.allowance + * ) + * ).wait(); + */ + override async getRequestExecuteAllowanceParams(transaction: { + contractAddress: Address; + calldata: string; + l2GasLimit?: BigNumberish; + l2Value?: BigNumberish; + factoryDeps?: BytesLike[]; + operatorTip?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: Overrides; + }): Promise<{token: Address; allowance: BigNumberish}> { + return super.getRequestExecuteAllowanceParams(transaction); + } + /** * @inheritDoc * @@ -1075,6 +1318,37 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { return super.getRequestExecuteTx(transaction); } + /** + * @inheritDoc + * + * @example + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * // Any L2 -> L1 transaction can be used. + * // In this case, withdrawal transaction is used. + * const tx = "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e"; + * console.log(`Confirmation data: ${utils.toJSON(await signer.getPriorityOpConfirmation(tx, 0))}`); + */ + override async getPriorityOpConfirmation( + txHash: string, + index = 0 + ): Promise<{ + l1BatchNumber: number; + l2MessageIndex: number; + l2TxNumberInBlock: number | null; + proof: string[]; + }> { + return super.getPriorityOpConfirmation(txHash, index); + } + /** * Creates a new L1Singer with provided `signer` and `zksyncProvider`. * diff --git a/src/typechain/IAllowList.ts b/src/typechain/IAllowList.ts deleted file mode 100644 index 1a513456..00000000 --- a/src/typechain/IAllowList.ts +++ /dev/null @@ -1,441 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -import type { - BaseContract, - BigNumberish, - BytesLike, - FunctionFragment, - Result, - Interface, - EventFragment, - AddressLike, - ContractRunner, - ContractMethod, - Listener, -} from "ethers"; -import type { - TypedContractEvent, - TypedDeferredTopicFilter, - TypedEventLog, - TypedLogDescription, - TypedListener, - TypedContractMethod, -} from "./common"; - -export declare namespace IAllowList { - export type DepositStruct = { - depositLimitation: boolean; - depositCap: BigNumberish; - }; - - export type DepositStructOutput = [ - depositLimitation: boolean, - depositCap: bigint - ] & { depositLimitation: boolean; depositCap: bigint }; -} - -export interface IAllowListInterface extends Interface { - getFunction( - nameOrSignature: - | "canCall" - | "getAccessMode" - | "getTokenDepositLimitData" - | "hasSpecialAccessToCall" - | "setAccessMode" - | "setBatchAccessMode" - | "setBatchPermissionToCall" - | "setDepositLimit" - | "setPermissionToCall" - ): FunctionFragment; - - getEvent( - nameOrSignatureOrTopic: - | "UpdateAccessMode" - | "UpdateCallPermission" - | "UpdateDepositLimit" - ): EventFragment; - - encodeFunctionData( - functionFragment: "canCall", - values: [AddressLike, AddressLike, BytesLike] - ): string; - encodeFunctionData( - functionFragment: "getAccessMode", - values: [AddressLike] - ): string; - encodeFunctionData( - functionFragment: "getTokenDepositLimitData", - values: [AddressLike] - ): string; - encodeFunctionData( - functionFragment: "hasSpecialAccessToCall", - values: [AddressLike, AddressLike, BytesLike] - ): string; - encodeFunctionData( - functionFragment: "setAccessMode", - values: [AddressLike, BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "setBatchAccessMode", - values: [AddressLike[], BigNumberish[]] - ): string; - encodeFunctionData( - functionFragment: "setBatchPermissionToCall", - values: [AddressLike[], AddressLike[], BytesLike[], boolean[]] - ): string; - encodeFunctionData( - functionFragment: "setDepositLimit", - values: [AddressLike, boolean, BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "setPermissionToCall", - values: [AddressLike, AddressLike, BytesLike, boolean] - ): string; - - decodeFunctionResult(functionFragment: "canCall", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "getAccessMode", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getTokenDepositLimitData", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "hasSpecialAccessToCall", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setAccessMode", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setBatchAccessMode", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setBatchPermissionToCall", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setDepositLimit", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setPermissionToCall", - data: BytesLike - ): Result; -} - -export namespace UpdateAccessModeEvent { - export type InputTuple = [ - target: AddressLike, - previousMode: BigNumberish, - newMode: BigNumberish - ]; - export type OutputTuple = [ - target: string, - previousMode: bigint, - newMode: bigint - ]; - export interface OutputObject { - target: string; - previousMode: bigint; - newMode: bigint; - } - export type Event = TypedContractEvent; - export type Filter = TypedDeferredTopicFilter; - export type Log = TypedEventLog; - export type LogDescription = TypedLogDescription; -} - -export namespace UpdateCallPermissionEvent { - export type InputTuple = [ - caller: AddressLike, - target: AddressLike, - functionSig: BytesLike, - status: boolean - ]; - export type OutputTuple = [ - caller: string, - target: string, - functionSig: string, - status: boolean - ]; - export interface OutputObject { - caller: string; - target: string; - functionSig: string; - status: boolean; - } - export type Event = TypedContractEvent; - export type Filter = TypedDeferredTopicFilter; - export type Log = TypedEventLog; - export type LogDescription = TypedLogDescription; -} - -export namespace UpdateDepositLimitEvent { - export type InputTuple = [ - l1Token: AddressLike, - depositLimitation: boolean, - depositCap: BigNumberish - ]; - export type OutputTuple = [ - l1Token: string, - depositLimitation: boolean, - depositCap: bigint - ]; - export interface OutputObject { - l1Token: string; - depositLimitation: boolean; - depositCap: bigint; - } - export type Event = TypedContractEvent; - export type Filter = TypedDeferredTopicFilter; - export type Log = TypedEventLog; - export type LogDescription = TypedLogDescription; -} - -export interface IAllowList extends BaseContract { - connect(runner?: ContractRunner | null): IAllowList; - waitForDeployment(): Promise; - - interface: IAllowListInterface; - - queryFilter( - event: TCEvent, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>>; - queryFilter( - filter: TypedDeferredTopicFilter, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>>; - - on( - event: TCEvent, - listener: TypedListener - ): Promise; - on( - filter: TypedDeferredTopicFilter, - listener: TypedListener - ): Promise; - - once( - event: TCEvent, - listener: TypedListener - ): Promise; - once( - filter: TypedDeferredTopicFilter, - listener: TypedListener - ): Promise; - - listeners( - event: TCEvent - ): Promise>>; - listeners(eventName?: string): Promise>; - removeAllListeners( - event?: TCEvent - ): Promise; - - canCall: TypedContractMethod< - [_caller: AddressLike, _target: AddressLike, _functionSig: BytesLike], - [boolean], - "view" - >; - - getAccessMode: TypedContractMethod<[_target: AddressLike], [bigint], "view">; - - getTokenDepositLimitData: TypedContractMethod< - [_l1Token: AddressLike], - [IAllowList.DepositStructOutput], - "view" - >; - - hasSpecialAccessToCall: TypedContractMethod< - [_caller: AddressLike, _target: AddressLike, _functionSig: BytesLike], - [boolean], - "view" - >; - - setAccessMode: TypedContractMethod< - [_target: AddressLike, _accessMode: BigNumberish], - [void], - "nonpayable" - >; - - setBatchAccessMode: TypedContractMethod< - [_targets: AddressLike[], _accessMode: BigNumberish[]], - [void], - "nonpayable" - >; - - setBatchPermissionToCall: TypedContractMethod< - [ - _callers: AddressLike[], - _targets: AddressLike[], - _functionSigs: BytesLike[], - _enables: boolean[] - ], - [void], - "nonpayable" - >; - - setDepositLimit: TypedContractMethod< - [ - _l1Token: AddressLike, - _depositLimitation: boolean, - _depositCap: BigNumberish - ], - [void], - "nonpayable" - >; - - setPermissionToCall: TypedContractMethod< - [ - _caller: AddressLike, - _target: AddressLike, - _functionSig: BytesLike, - _enable: boolean - ], - [void], - "nonpayable" - >; - - getFunction( - key: string | FunctionFragment - ): T; - - getFunction( - nameOrSignature: "canCall" - ): TypedContractMethod< - [_caller: AddressLike, _target: AddressLike, _functionSig: BytesLike], - [boolean], - "view" - >; - getFunction( - nameOrSignature: "getAccessMode" - ): TypedContractMethod<[_target: AddressLike], [bigint], "view">; - getFunction( - nameOrSignature: "getTokenDepositLimitData" - ): TypedContractMethod< - [_l1Token: AddressLike], - [IAllowList.DepositStructOutput], - "view" - >; - getFunction( - nameOrSignature: "hasSpecialAccessToCall" - ): TypedContractMethod< - [_caller: AddressLike, _target: AddressLike, _functionSig: BytesLike], - [boolean], - "view" - >; - getFunction( - nameOrSignature: "setAccessMode" - ): TypedContractMethod< - [_target: AddressLike, _accessMode: BigNumberish], - [void], - "nonpayable" - >; - getFunction( - nameOrSignature: "setBatchAccessMode" - ): TypedContractMethod< - [_targets: AddressLike[], _accessMode: BigNumberish[]], - [void], - "nonpayable" - >; - getFunction( - nameOrSignature: "setBatchPermissionToCall" - ): TypedContractMethod< - [ - _callers: AddressLike[], - _targets: AddressLike[], - _functionSigs: BytesLike[], - _enables: boolean[] - ], - [void], - "nonpayable" - >; - getFunction( - nameOrSignature: "setDepositLimit" - ): TypedContractMethod< - [ - _l1Token: AddressLike, - _depositLimitation: boolean, - _depositCap: BigNumberish - ], - [void], - "nonpayable" - >; - getFunction( - nameOrSignature: "setPermissionToCall" - ): TypedContractMethod< - [ - _caller: AddressLike, - _target: AddressLike, - _functionSig: BytesLike, - _enable: boolean - ], - [void], - "nonpayable" - >; - - getEvent( - key: "UpdateAccessMode" - ): TypedContractEvent< - UpdateAccessModeEvent.InputTuple, - UpdateAccessModeEvent.OutputTuple, - UpdateAccessModeEvent.OutputObject - >; - getEvent( - key: "UpdateCallPermission" - ): TypedContractEvent< - UpdateCallPermissionEvent.InputTuple, - UpdateCallPermissionEvent.OutputTuple, - UpdateCallPermissionEvent.OutputObject - >; - getEvent( - key: "UpdateDepositLimit" - ): TypedContractEvent< - UpdateDepositLimitEvent.InputTuple, - UpdateDepositLimitEvent.OutputTuple, - UpdateDepositLimitEvent.OutputObject - >; - - filters: { - "UpdateAccessMode(address,uint8,uint8)": TypedContractEvent< - UpdateAccessModeEvent.InputTuple, - UpdateAccessModeEvent.OutputTuple, - UpdateAccessModeEvent.OutputObject - >; - UpdateAccessMode: TypedContractEvent< - UpdateAccessModeEvent.InputTuple, - UpdateAccessModeEvent.OutputTuple, - UpdateAccessModeEvent.OutputObject - >; - - "UpdateCallPermission(address,address,bytes4,bool)": TypedContractEvent< - UpdateCallPermissionEvent.InputTuple, - UpdateCallPermissionEvent.OutputTuple, - UpdateCallPermissionEvent.OutputObject - >; - UpdateCallPermission: TypedContractEvent< - UpdateCallPermissionEvent.InputTuple, - UpdateCallPermissionEvent.OutputTuple, - UpdateCallPermissionEvent.OutputObject - >; - - "UpdateDepositLimit(address,bool,uint256)": TypedContractEvent< - UpdateDepositLimitEvent.InputTuple, - UpdateDepositLimitEvent.OutputTuple, - UpdateDepositLimitEvent.OutputObject - >; - UpdateDepositLimit: TypedContractEvent< - UpdateDepositLimitEvent.InputTuple, - UpdateDepositLimitEvent.OutputTuple, - UpdateDepositLimitEvent.OutputObject - >; - }; -} diff --git a/src/typechain/IBridgehub.ts b/src/typechain/IBridgehub.ts new file mode 100644 index 00000000..82688f66 --- /dev/null +++ b/src/typechain/IBridgehub.ts @@ -0,0 +1,743 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + EventFragment, + AddressLike, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedLogDescription, + TypedListener, + TypedContractMethod, +} from "./common"; + +export type L2LogStruct = { + l2ShardId: BigNumberish; + isService: boolean; + txNumberInBatch: BigNumberish; + sender: AddressLike; + key: BytesLike; + value: BytesLike; +}; + +export type L2LogStructOutput = [ + l2ShardId: bigint, + isService: boolean, + txNumberInBatch: bigint, + sender: string, + key: string, + value: string +] & { + l2ShardId: bigint; + isService: boolean; + txNumberInBatch: bigint; + sender: string; + key: string; + value: string; +}; + +export type L2MessageStruct = { + txNumberInBatch: BigNumberish; + sender: AddressLike; + data: BytesLike; +}; + +export type L2MessageStructOutput = [ + txNumberInBatch: bigint, + sender: string, + data: string +] & { txNumberInBatch: bigint; sender: string; data: string }; + +export type L2TransactionRequestDirectStruct = { + chainId: BigNumberish; + mintValue: BigNumberish; + l2Contract: AddressLike; + l2Value: BigNumberish; + l2Calldata: BytesLike; + l2GasLimit: BigNumberish; + l2GasPerPubdataByteLimit: BigNumberish; + factoryDeps: BytesLike[]; + refundRecipient: AddressLike; +}; + +export type L2TransactionRequestDirectStructOutput = [ + chainId: bigint, + mintValue: bigint, + l2Contract: string, + l2Value: bigint, + l2Calldata: string, + l2GasLimit: bigint, + l2GasPerPubdataByteLimit: bigint, + factoryDeps: string[], + refundRecipient: string +] & { + chainId: bigint; + mintValue: bigint; + l2Contract: string; + l2Value: bigint; + l2Calldata: string; + l2GasLimit: bigint; + l2GasPerPubdataByteLimit: bigint; + factoryDeps: string[]; + refundRecipient: string; +}; + +export type L2TransactionRequestTwoBridgesOuterStruct = { + chainId: BigNumberish; + mintValue: BigNumberish; + l2Value: BigNumberish; + l2GasLimit: BigNumberish; + l2GasPerPubdataByteLimit: BigNumberish; + refundRecipient: AddressLike; + secondBridgeAddress: AddressLike; + secondBridgeValue: BigNumberish; + secondBridgeCalldata: BytesLike; +}; + +export type L2TransactionRequestTwoBridgesOuterStructOutput = [ + chainId: bigint, + mintValue: bigint, + l2Value: bigint, + l2GasLimit: bigint, + l2GasPerPubdataByteLimit: bigint, + refundRecipient: string, + secondBridgeAddress: string, + secondBridgeValue: bigint, + secondBridgeCalldata: string +] & { + chainId: bigint; + mintValue: bigint; + l2Value: bigint; + l2GasLimit: bigint; + l2GasPerPubdataByteLimit: bigint; + refundRecipient: string; + secondBridgeAddress: string; + secondBridgeValue: bigint; + secondBridgeCalldata: string; +}; + +export interface IBridgehubInterface extends Interface { + getFunction( + nameOrSignature: + | "acceptAdmin" + | "addStateTransitionManager" + | "addToken" + | "baseToken" + | "createNewChain" + | "getStateTransition" + | "l2TransactionBaseCost" + | "proveL1ToL2TransactionStatus" + | "proveL2LogInclusion" + | "proveL2MessageInclusion" + | "removeStateTransitionManager" + | "requestL2TransactionDirect" + | "requestL2TransactionTwoBridges" + | "setPendingAdmin" + | "setSharedBridge" + | "sharedBridge" + | "stateTransitionManager" + | "stateTransitionManagerIsRegistered" + | "tokenIsRegistered" + ): FunctionFragment; + + getEvent( + nameOrSignatureOrTopic: "NewAdmin" | "NewChain" | "NewPendingAdmin" + ): EventFragment; + + encodeFunctionData( + functionFragment: "acceptAdmin", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "addStateTransitionManager", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "addToken", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "baseToken", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "createNewChain", + values: [ + BigNumberish, + AddressLike, + AddressLike, + BigNumberish, + AddressLike, + BytesLike + ] + ): string; + encodeFunctionData( + functionFragment: "getStateTransition", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "l2TransactionBaseCost", + values: [BigNumberish, BigNumberish, BigNumberish, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "proveL1ToL2TransactionStatus", + values: [ + BigNumberish, + BytesLike, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike[], + BigNumberish + ] + ): string; + encodeFunctionData( + functionFragment: "proveL2LogInclusion", + values: [BigNumberish, BigNumberish, BigNumberish, L2LogStruct, BytesLike[]] + ): string; + encodeFunctionData( + functionFragment: "proveL2MessageInclusion", + values: [ + BigNumberish, + BigNumberish, + BigNumberish, + L2MessageStruct, + BytesLike[] + ] + ): string; + encodeFunctionData( + functionFragment: "removeStateTransitionManager", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "requestL2TransactionDirect", + values: [L2TransactionRequestDirectStruct] + ): string; + encodeFunctionData( + functionFragment: "requestL2TransactionTwoBridges", + values: [L2TransactionRequestTwoBridgesOuterStruct] + ): string; + encodeFunctionData( + functionFragment: "setPendingAdmin", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "setSharedBridge", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "sharedBridge", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "stateTransitionManager", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "stateTransitionManagerIsRegistered", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "tokenIsRegistered", + values: [AddressLike] + ): string; + + decodeFunctionResult( + functionFragment: "acceptAdmin", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "addStateTransitionManager", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "addToken", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "baseToken", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "createNewChain", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getStateTransition", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "l2TransactionBaseCost", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "proveL1ToL2TransactionStatus", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "proveL2LogInclusion", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "proveL2MessageInclusion", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "removeStateTransitionManager", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "requestL2TransactionDirect", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "requestL2TransactionTwoBridges", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setPendingAdmin", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setSharedBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "sharedBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "stateTransitionManager", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "stateTransitionManagerIsRegistered", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "tokenIsRegistered", + data: BytesLike + ): Result; +} + +export namespace NewAdminEvent { + export type InputTuple = [oldAdmin: AddressLike, newAdmin: AddressLike]; + export type OutputTuple = [oldAdmin: string, newAdmin: string]; + export interface OutputObject { + oldAdmin: string; + newAdmin: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace NewChainEvent { + export type InputTuple = [ + chainId: BigNumberish, + stateTransitionManager: AddressLike, + chainGovernance: AddressLike + ]; + export type OutputTuple = [ + chainId: bigint, + stateTransitionManager: string, + chainGovernance: string + ]; + export interface OutputObject { + chainId: bigint; + stateTransitionManager: string; + chainGovernance: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace NewPendingAdminEvent { + export type InputTuple = [ + oldPendingAdmin: AddressLike, + newPendingAdmin: AddressLike + ]; + export type OutputTuple = [oldPendingAdmin: string, newPendingAdmin: string]; + export interface OutputObject { + oldPendingAdmin: string; + newPendingAdmin: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export interface IBridgehub extends BaseContract { + connect(runner?: ContractRunner | null): IBridgehub; + waitForDeployment(): Promise; + + interface: IBridgehubInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + acceptAdmin: TypedContractMethod<[], [void], "nonpayable">; + + addStateTransitionManager: TypedContractMethod< + [_stateTransitionManager: AddressLike], + [void], + "nonpayable" + >; + + addToken: TypedContractMethod<[_token: AddressLike], [void], "nonpayable">; + + baseToken: TypedContractMethod<[_chainId: BigNumberish], [string], "view">; + + createNewChain: TypedContractMethod< + [ + _chainId: BigNumberish, + _stateTransitionManager: AddressLike, + _baseToken: AddressLike, + _salt: BigNumberish, + _admin: AddressLike, + _initData: BytesLike + ], + [bigint], + "nonpayable" + >; + + getStateTransition: TypedContractMethod< + [_chainId: BigNumberish], + [string], + "view" + >; + + l2TransactionBaseCost: TypedContractMethod< + [ + _chainId: BigNumberish, + _gasPrice: BigNumberish, + _l2GasLimit: BigNumberish, + _l2GasPerPubdataByteLimit: BigNumberish + ], + [bigint], + "view" + >; + + proveL1ToL2TransactionStatus: TypedContractMethod< + [ + _chainId: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[], + _status: BigNumberish + ], + [boolean], + "view" + >; + + proveL2LogInclusion: TypedContractMethod< + [ + _chainId: BigNumberish, + _batchNumber: BigNumberish, + _index: BigNumberish, + _log: L2LogStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + + proveL2MessageInclusion: TypedContractMethod< + [ + _chainId: BigNumberish, + _batchNumber: BigNumberish, + _index: BigNumberish, + _message: L2MessageStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + + removeStateTransitionManager: TypedContractMethod< + [_stateTransitionManager: AddressLike], + [void], + "nonpayable" + >; + + requestL2TransactionDirect: TypedContractMethod< + [_request: L2TransactionRequestDirectStruct], + [string], + "payable" + >; + + requestL2TransactionTwoBridges: TypedContractMethod< + [_request: L2TransactionRequestTwoBridgesOuterStruct], + [string], + "payable" + >; + + setPendingAdmin: TypedContractMethod< + [_newPendingAdmin: AddressLike], + [void], + "nonpayable" + >; + + setSharedBridge: TypedContractMethod< + [_sharedBridge: AddressLike], + [void], + "nonpayable" + >; + + sharedBridge: TypedContractMethod<[], [string], "view">; + + stateTransitionManager: TypedContractMethod< + [_chainId: BigNumberish], + [string], + "view" + >; + + stateTransitionManagerIsRegistered: TypedContractMethod< + [_stateTransitionManager: AddressLike], + [boolean], + "view" + >; + + tokenIsRegistered: TypedContractMethod< + [_baseToken: AddressLike], + [boolean], + "view" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "acceptAdmin" + ): TypedContractMethod<[], [void], "nonpayable">; + getFunction( + nameOrSignature: "addStateTransitionManager" + ): TypedContractMethod< + [_stateTransitionManager: AddressLike], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "addToken" + ): TypedContractMethod<[_token: AddressLike], [void], "nonpayable">; + getFunction( + nameOrSignature: "baseToken" + ): TypedContractMethod<[_chainId: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "createNewChain" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _stateTransitionManager: AddressLike, + _baseToken: AddressLike, + _salt: BigNumberish, + _admin: AddressLike, + _initData: BytesLike + ], + [bigint], + "nonpayable" + >; + getFunction( + nameOrSignature: "getStateTransition" + ): TypedContractMethod<[_chainId: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "l2TransactionBaseCost" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _gasPrice: BigNumberish, + _l2GasLimit: BigNumberish, + _l2GasPerPubdataByteLimit: BigNumberish + ], + [bigint], + "view" + >; + getFunction( + nameOrSignature: "proveL1ToL2TransactionStatus" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[], + _status: BigNumberish + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "proveL2LogInclusion" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _batchNumber: BigNumberish, + _index: BigNumberish, + _log: L2LogStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "proveL2MessageInclusion" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _batchNumber: BigNumberish, + _index: BigNumberish, + _message: L2MessageStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "removeStateTransitionManager" + ): TypedContractMethod< + [_stateTransitionManager: AddressLike], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "requestL2TransactionDirect" + ): TypedContractMethod< + [_request: L2TransactionRequestDirectStruct], + [string], + "payable" + >; + getFunction( + nameOrSignature: "requestL2TransactionTwoBridges" + ): TypedContractMethod< + [_request: L2TransactionRequestTwoBridgesOuterStruct], + [string], + "payable" + >; + getFunction( + nameOrSignature: "setPendingAdmin" + ): TypedContractMethod<[_newPendingAdmin: AddressLike], [void], "nonpayable">; + getFunction( + nameOrSignature: "setSharedBridge" + ): TypedContractMethod<[_sharedBridge: AddressLike], [void], "nonpayable">; + getFunction( + nameOrSignature: "sharedBridge" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "stateTransitionManager" + ): TypedContractMethod<[_chainId: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "stateTransitionManagerIsRegistered" + ): TypedContractMethod< + [_stateTransitionManager: AddressLike], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "tokenIsRegistered" + ): TypedContractMethod<[_baseToken: AddressLike], [boolean], "view">; + + getEvent( + key: "NewAdmin" + ): TypedContractEvent< + NewAdminEvent.InputTuple, + NewAdminEvent.OutputTuple, + NewAdminEvent.OutputObject + >; + getEvent( + key: "NewChain" + ): TypedContractEvent< + NewChainEvent.InputTuple, + NewChainEvent.OutputTuple, + NewChainEvent.OutputObject + >; + getEvent( + key: "NewPendingAdmin" + ): TypedContractEvent< + NewPendingAdminEvent.InputTuple, + NewPendingAdminEvent.OutputTuple, + NewPendingAdminEvent.OutputObject + >; + + filters: { + "NewAdmin(address,address)": TypedContractEvent< + NewAdminEvent.InputTuple, + NewAdminEvent.OutputTuple, + NewAdminEvent.OutputObject + >; + NewAdmin: TypedContractEvent< + NewAdminEvent.InputTuple, + NewAdminEvent.OutputTuple, + NewAdminEvent.OutputObject + >; + + "NewChain(uint256,address,address)": TypedContractEvent< + NewChainEvent.InputTuple, + NewChainEvent.OutputTuple, + NewChainEvent.OutputObject + >; + NewChain: TypedContractEvent< + NewChainEvent.InputTuple, + NewChainEvent.OutputTuple, + NewChainEvent.OutputObject + >; + + "NewPendingAdmin(address,address)": TypedContractEvent< + NewPendingAdminEvent.InputTuple, + NewPendingAdminEvent.OutputTuple, + NewPendingAdminEvent.OutputObject + >; + NewPendingAdmin: TypedContractEvent< + NewPendingAdminEvent.InputTuple, + NewPendingAdminEvent.OutputTuple, + NewPendingAdminEvent.OutputObject + >; + }; +} diff --git a/src/typechain/IContractDeployer.ts b/src/typechain/IContractDeployer.ts index fa895ec3..be362c11 100644 --- a/src/typechain/IContractDeployer.ts +++ b/src/typechain/IContractDeployer.ts @@ -23,6 +23,30 @@ import type { TypedContractMethod, } from "./common"; +export declare namespace ContractDeployer { + export type ForceDeploymentStruct = { + bytecodeHash: BytesLike; + newAddress: AddressLike; + callConstructor: boolean; + value: BigNumberish; + input: BytesLike; + }; + + export type ForceDeploymentStructOutput = [ + bytecodeHash: string, + newAddress: string, + callConstructor: boolean, + value: bigint, + input: string + ] & { + bytecodeHash: string; + newAddress: string; + callConstructor: boolean; + value: bigint; + input: string; + }; +} + export declare namespace IContractDeployer { export type AccountInfoStruct = { supportedAAVersion: BigNumberish; @@ -42,6 +66,9 @@ export interface IContractDeployerInterface extends Interface { | "create2" | "create2Account" | "createAccount" + | "extendedAccountVersion" + | "forceDeployOnAddress" + | "forceDeployOnAddresses" | "getAccountInfo" | "getNewAddressCreate" | "getNewAddressCreate2" @@ -72,6 +99,18 @@ export interface IContractDeployerInterface extends Interface { functionFragment: "createAccount", values: [BytesLike, BytesLike, BytesLike, BigNumberish] ): string; + encodeFunctionData( + functionFragment: "extendedAccountVersion", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "forceDeployOnAddress", + values: [ContractDeployer.ForceDeploymentStruct, AddressLike] + ): string; + encodeFunctionData( + functionFragment: "forceDeployOnAddresses", + values: [ContractDeployer.ForceDeploymentStruct[]] + ): string; encodeFunctionData( functionFragment: "getAccountInfo", values: [AddressLike] @@ -103,6 +142,18 @@ export interface IContractDeployerInterface extends Interface { functionFragment: "createAccount", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "extendedAccountVersion", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "forceDeployOnAddress", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "forceDeployOnAddresses", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "getAccountInfo", data: BytesLike @@ -247,7 +298,7 @@ export interface IContractDeployer extends BaseContract { createAccount: TypedContractMethod< [ - _salt: BytesLike, + arg0: BytesLike, _bytecodeHash: BytesLike, _input: BytesLike, _aaVersion: BigNumberish @@ -256,6 +307,24 @@ export interface IContractDeployer extends BaseContract { "payable" >; + extendedAccountVersion: TypedContractMethod< + [_address: AddressLike], + [bigint], + "view" + >; + + forceDeployOnAddress: TypedContractMethod< + [_deployment: ContractDeployer.ForceDeploymentStruct, _sender: AddressLike], + [void], + "payable" + >; + + forceDeployOnAddresses: TypedContractMethod< + [_deployments: ContractDeployer.ForceDeploymentStruct[]], + [void], + "payable" + >; + getAccountInfo: TypedContractMethod< [_address: AddressLike], [IContractDeployer.AccountInfoStructOutput], @@ -325,7 +394,7 @@ export interface IContractDeployer extends BaseContract { nameOrSignature: "createAccount" ): TypedContractMethod< [ - _salt: BytesLike, + arg0: BytesLike, _bytecodeHash: BytesLike, _input: BytesLike, _aaVersion: BigNumberish @@ -333,6 +402,23 @@ export interface IContractDeployer extends BaseContract { [string], "payable" >; + getFunction( + nameOrSignature: "extendedAccountVersion" + ): TypedContractMethod<[_address: AddressLike], [bigint], "view">; + getFunction( + nameOrSignature: "forceDeployOnAddress" + ): TypedContractMethod< + [_deployment: ContractDeployer.ForceDeploymentStruct, _sender: AddressLike], + [void], + "payable" + >; + getFunction( + nameOrSignature: "forceDeployOnAddresses" + ): TypedContractMethod< + [_deployments: ContractDeployer.ForceDeploymentStruct[]], + [void], + "payable" + >; getFunction( nameOrSignature: "getAccountInfo" ): TypedContractMethod< diff --git a/src/typechain/IL1Bridge.ts b/src/typechain/IL1Bridge.ts index 11a60cf1..e1461a73 100644 --- a/src/typechain/IL1Bridge.ts +++ b/src/typechain/IL1Bridge.ts @@ -23,29 +23,72 @@ import type { TypedContractMethod, } from "./common"; +export type L2TransactionRequestTwoBridgesInnerStruct = { + magicValue: BytesLike; + l2Contract: AddressLike; + l2Calldata: BytesLike; + factoryDeps: BytesLike[]; + txDataHash: BytesLike; +}; + +export type L2TransactionRequestTwoBridgesInnerStructOutput = [ + magicValue: string, + l2Contract: string, + l2Calldata: string, + factoryDeps: string[], + txDataHash: string +] & { + magicValue: string; + l2Contract: string; + l2Calldata: string; + factoryDeps: string[]; + txDataHash: string; +}; + export interface IL1BridgeInterface extends Interface { getFunction( nameOrSignature: + | "bridgehub" + | "bridgehubConfirmL2Transaction" + | "bridgehubDeposit" + | "bridgehubDepositBaseToken" | "claimFailedDeposit" | "deposit" + | "depositHappened" | "finalizeWithdrawal" - | "isWithdrawalFinalized" - | "l2Bridge" - | "l2TokenAddress" + | "isWithdrawalFinalizedShared" + | "l2BridgeAddress" ): FunctionFragment; getEvent( nameOrSignatureOrTopic: - | "ClaimedFailedDeposit" - | "DepositInitiated" - | "WithdrawalFinalized" + | "BridgehubDepositFinalized" + | "BridgehubDepositInitiatedSharedBridge" + | "ClaimedFailedDepositSharedBridge" + | "DepositInitiatedSharedBridge" + | "WithdrawalFinalizedSharedBridge" ): EventFragment; + encodeFunctionData(functionFragment: "bridgehub", values?: undefined): string; + encodeFunctionData( + functionFragment: "bridgehubConfirmL2Transaction", + values: [BigNumberish, BytesLike, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "bridgehubDeposit", + values: [BigNumberish, AddressLike, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "bridgehubDepositBaseToken", + values: [BigNumberish, AddressLike, AddressLike, BigNumberish] + ): string; encodeFunctionData( functionFragment: "claimFailedDeposit", values: [ + BigNumberish, AddressLike, AddressLike, + BigNumberish, BytesLike, BigNumberish, BigNumberish, @@ -56,56 +99,119 @@ export interface IL1BridgeInterface extends Interface { encodeFunctionData( functionFragment: "deposit", values: [ + BigNumberish, AddressLike, AddressLike, BigNumberish, BigNumberish, BigNumberish, + BigNumberish, AddressLike ] ): string; + encodeFunctionData( + functionFragment: "depositHappened", + values: [BigNumberish, BytesLike] + ): string; encodeFunctionData( functionFragment: "finalizeWithdrawal", - values: [BigNumberish, BigNumberish, BigNumberish, BytesLike, BytesLike[]] + values: [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike, + BytesLike[] + ] ): string; encodeFunctionData( - functionFragment: "isWithdrawalFinalized", - values: [BigNumberish, BigNumberish] + functionFragment: "isWithdrawalFinalizedShared", + values: [BigNumberish, BigNumberish, BigNumberish] ): string; - encodeFunctionData(functionFragment: "l2Bridge", values?: undefined): string; encodeFunctionData( - functionFragment: "l2TokenAddress", - values: [AddressLike] + functionFragment: "l2BridgeAddress", + values: [BigNumberish] ): string; + decodeFunctionResult(functionFragment: "bridgehub", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "bridgehubConfirmL2Transaction", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "bridgehubDeposit", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "bridgehubDepositBaseToken", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "claimFailedDeposit", data: BytesLike ): Result; decodeFunctionResult(functionFragment: "deposit", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "depositHappened", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "finalizeWithdrawal", data: BytesLike ): Result; decodeFunctionResult( - functionFragment: "isWithdrawalFinalized", + functionFragment: "isWithdrawalFinalizedShared", data: BytesLike ): Result; - decodeFunctionResult(functionFragment: "l2Bridge", data: BytesLike): Result; decodeFunctionResult( - functionFragment: "l2TokenAddress", + functionFragment: "l2BridgeAddress", data: BytesLike ): Result; } -export namespace ClaimedFailedDepositEvent { +export namespace BridgehubDepositFinalizedEvent { + export type InputTuple = [ + chainId: BigNumberish, + txDataHash: BytesLike, + l2DepositTxHash: BytesLike + ]; + export type OutputTuple = [ + chainId: bigint, + txDataHash: string, + l2DepositTxHash: string + ]; + export interface OutputObject { + chainId: bigint; + txDataHash: string; + l2DepositTxHash: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace BridgehubDepositInitiatedSharedBridgeEvent { export type InputTuple = [ + chainId: BigNumberish, + txDataHash: BytesLike, + from: AddressLike, to: AddressLike, l1Token: AddressLike, amount: BigNumberish ]; - export type OutputTuple = [to: string, l1Token: string, amount: bigint]; + export type OutputTuple = [ + chainId: bigint, + txDataHash: string, + from: string, + to: string, + l1Token: string, + amount: bigint + ]; export interface OutputObject { + chainId: bigint; + txDataHash: string; + from: string; to: string; l1Token: string; amount: bigint; @@ -116,8 +222,34 @@ export namespace ClaimedFailedDepositEvent { export type LogDescription = TypedLogDescription; } -export namespace DepositInitiatedEvent { +export namespace ClaimedFailedDepositSharedBridgeEvent { export type InputTuple = [ + chainId: BigNumberish, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace DepositInitiatedSharedBridgeEvent { + export type InputTuple = [ + chainId: BigNumberish, l2DepositTxHash: BytesLike, from: AddressLike, to: AddressLike, @@ -125,6 +257,7 @@ export namespace DepositInitiatedEvent { amount: BigNumberish ]; export type OutputTuple = [ + chainId: bigint, l2DepositTxHash: string, from: string, to: string, @@ -132,6 +265,7 @@ export namespace DepositInitiatedEvent { amount: bigint ]; export interface OutputObject { + chainId: bigint; l2DepositTxHash: string; from: string; to: string; @@ -144,14 +278,21 @@ export namespace DepositInitiatedEvent { export type LogDescription = TypedLogDescription; } -export namespace WithdrawalFinalizedEvent { +export namespace WithdrawalFinalizedSharedBridgeEvent { export type InputTuple = [ + chainId: BigNumberish, to: AddressLike, l1Token: AddressLike, amount: BigNumberish ]; - export type OutputTuple = [to: string, l1Token: string, amount: bigint]; + export type OutputTuple = [ + chainId: bigint, + to: string, + l1Token: string, + amount: bigint + ]; export interface OutputObject { + chainId: bigint; to: string; l1Token: string; amount: bigint; @@ -205,10 +346,37 @@ export interface IL1Bridge extends BaseContract { event?: TCEvent ): Promise; + bridgehub: TypedContractMethod<[], [string], "view">; + + bridgehubConfirmL2Transaction: TypedContractMethod< + [_chainId: BigNumberish, _txDataHash: BytesLike, _txHash: BytesLike], + [void], + "nonpayable" + >; + + bridgehubDeposit: TypedContractMethod< + [_chainId: BigNumberish, _prevMsgSender: AddressLike, _data: BytesLike], + [L2TransactionRequestTwoBridgesInnerStructOutput], + "payable" + >; + + bridgehubDepositBaseToken: TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish + ], + [void], + "payable" + >; + claimFailedDeposit: TypedContractMethod< [ + _chainId: BigNumberish, _depositSender: AddressLike, _l1Token: AddressLike, + _amount: BigNumberish, _l2TxHash: BytesLike, _l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish, @@ -221,8 +389,10 @@ export interface IL1Bridge extends BaseContract { deposit: TypedContractMethod< [ + _chainId: BigNumberish, _l2Receiver: AddressLike, _l1Token: AddressLike, + _mintValue: BigNumberish, _amount: BigNumberish, _l2TxGasLimit: BigNumberish, _l2TxGasPerPubdataByte: BigNumberish, @@ -232,8 +402,15 @@ export interface IL1Bridge extends BaseContract { "payable" >; + depositHappened: TypedContractMethod< + [_chainId: BigNumberish, _l2TxHash: BytesLike], + [string], + "view" + >; + finalizeWithdrawal: TypedContractMethod< [ + _chainId: BigNumberish, _l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish, _l2TxNumberInBatch: BigNumberish, @@ -244,16 +421,18 @@ export interface IL1Bridge extends BaseContract { "nonpayable" >; - isWithdrawalFinalized: TypedContractMethod< - [_l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish], + isWithdrawalFinalizedShared: TypedContractMethod< + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish + ], [boolean], "view" >; - l2Bridge: TypedContractMethod<[], [string], "view">; - - l2TokenAddress: TypedContractMethod< - [_l1Token: AddressLike], + l2BridgeAddress: TypedContractMethod< + [_chainId: BigNumberish], [string], "view" >; @@ -262,12 +441,43 @@ export interface IL1Bridge extends BaseContract { key: string | FunctionFragment ): T; + getFunction( + nameOrSignature: "bridgehub" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "bridgehubConfirmL2Transaction" + ): TypedContractMethod< + [_chainId: BigNumberish, _txDataHash: BytesLike, _txHash: BytesLike], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "bridgehubDeposit" + ): TypedContractMethod< + [_chainId: BigNumberish, _prevMsgSender: AddressLike, _data: BytesLike], + [L2TransactionRequestTwoBridgesInnerStructOutput], + "payable" + >; + getFunction( + nameOrSignature: "bridgehubDepositBaseToken" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish + ], + [void], + "payable" + >; getFunction( nameOrSignature: "claimFailedDeposit" ): TypedContractMethod< [ + _chainId: BigNumberish, _depositSender: AddressLike, _l1Token: AddressLike, + _amount: BigNumberish, _l2TxHash: BytesLike, _l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish, @@ -281,8 +491,10 @@ export interface IL1Bridge extends BaseContract { nameOrSignature: "deposit" ): TypedContractMethod< [ + _chainId: BigNumberish, _l2Receiver: AddressLike, _l1Token: AddressLike, + _mintValue: BigNumberish, _amount: BigNumberish, _l2TxGasLimit: BigNumberish, _l2TxGasPerPubdataByte: BigNumberish, @@ -291,10 +503,18 @@ export interface IL1Bridge extends BaseContract { [string], "payable" >; + getFunction( + nameOrSignature: "depositHappened" + ): TypedContractMethod< + [_chainId: BigNumberish, _l2TxHash: BytesLike], + [string], + "view" + >; getFunction( nameOrSignature: "finalizeWithdrawal" ): TypedContractMethod< [ + _chainId: BigNumberish, _l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish, _l2TxNumberInBatch: BigNumberish, @@ -305,73 +525,110 @@ export interface IL1Bridge extends BaseContract { "nonpayable" >; getFunction( - nameOrSignature: "isWithdrawalFinalized" + nameOrSignature: "isWithdrawalFinalizedShared" ): TypedContractMethod< - [_l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish], + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish + ], [boolean], "view" >; getFunction( - nameOrSignature: "l2Bridge" - ): TypedContractMethod<[], [string], "view">; - getFunction( - nameOrSignature: "l2TokenAddress" - ): TypedContractMethod<[_l1Token: AddressLike], [string], "view">; + nameOrSignature: "l2BridgeAddress" + ): TypedContractMethod<[_chainId: BigNumberish], [string], "view">; getEvent( - key: "ClaimedFailedDeposit" + key: "BridgehubDepositFinalized" + ): TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + getEvent( + key: "BridgehubDepositInitiatedSharedBridge" ): TypedContractEvent< - ClaimedFailedDepositEvent.InputTuple, - ClaimedFailedDepositEvent.OutputTuple, - ClaimedFailedDepositEvent.OutputObject + BridgehubDepositInitiatedSharedBridgeEvent.InputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputObject >; getEvent( - key: "DepositInitiated" + key: "ClaimedFailedDepositSharedBridge" ): TypedContractEvent< - DepositInitiatedEvent.InputTuple, - DepositInitiatedEvent.OutputTuple, - DepositInitiatedEvent.OutputObject + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject >; getEvent( - key: "WithdrawalFinalized" + key: "DepositInitiatedSharedBridge" ): TypedContractEvent< - WithdrawalFinalizedEvent.InputTuple, - WithdrawalFinalizedEvent.OutputTuple, - WithdrawalFinalizedEvent.OutputObject + DepositInitiatedSharedBridgeEvent.InputTuple, + DepositInitiatedSharedBridgeEvent.OutputTuple, + DepositInitiatedSharedBridgeEvent.OutputObject + >; + getEvent( + key: "WithdrawalFinalizedSharedBridge" + ): TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject >; filters: { - "ClaimedFailedDeposit(address,address,uint256)": TypedContractEvent< - ClaimedFailedDepositEvent.InputTuple, - ClaimedFailedDepositEvent.OutputTuple, - ClaimedFailedDepositEvent.OutputObject + "BridgehubDepositFinalized(uint256,bytes32,bytes32)": TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + BridgehubDepositFinalized: TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + + "BridgehubDepositInitiatedSharedBridge(uint256,bytes32,address,address,address,uint256)": TypedContractEvent< + BridgehubDepositInitiatedSharedBridgeEvent.InputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputObject + >; + BridgehubDepositInitiatedSharedBridge: TypedContractEvent< + BridgehubDepositInitiatedSharedBridgeEvent.InputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputObject + >; + + "ClaimedFailedDepositSharedBridge(uint256,address,address,uint256)": TypedContractEvent< + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject >; - ClaimedFailedDeposit: TypedContractEvent< - ClaimedFailedDepositEvent.InputTuple, - ClaimedFailedDepositEvent.OutputTuple, - ClaimedFailedDepositEvent.OutputObject + ClaimedFailedDepositSharedBridge: TypedContractEvent< + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject >; - "DepositInitiated(bytes32,address,address,address,uint256)": TypedContractEvent< - DepositInitiatedEvent.InputTuple, - DepositInitiatedEvent.OutputTuple, - DepositInitiatedEvent.OutputObject + "DepositInitiatedSharedBridge(uint256,bytes32,address,address,address,uint256)": TypedContractEvent< + DepositInitiatedSharedBridgeEvent.InputTuple, + DepositInitiatedSharedBridgeEvent.OutputTuple, + DepositInitiatedSharedBridgeEvent.OutputObject >; - DepositInitiated: TypedContractEvent< - DepositInitiatedEvent.InputTuple, - DepositInitiatedEvent.OutputTuple, - DepositInitiatedEvent.OutputObject + DepositInitiatedSharedBridge: TypedContractEvent< + DepositInitiatedSharedBridgeEvent.InputTuple, + DepositInitiatedSharedBridgeEvent.OutputTuple, + DepositInitiatedSharedBridgeEvent.OutputObject >; - "WithdrawalFinalized(address,address,uint256)": TypedContractEvent< - WithdrawalFinalizedEvent.InputTuple, - WithdrawalFinalizedEvent.OutputTuple, - WithdrawalFinalizedEvent.OutputObject + "WithdrawalFinalizedSharedBridge(uint256,address,address,uint256)": TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject >; - WithdrawalFinalized: TypedContractEvent< - WithdrawalFinalizedEvent.InputTuple, - WithdrawalFinalizedEvent.OutputTuple, - WithdrawalFinalizedEvent.OutputObject + WithdrawalFinalizedSharedBridge: TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject >; }; } diff --git a/src/typechain/IL1ERC20Bridge.ts b/src/typechain/IL1ERC20Bridge.ts new file mode 100644 index 00000000..ac3d9395 --- /dev/null +++ b/src/typechain/IL1ERC20Bridge.ts @@ -0,0 +1,486 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + EventFragment, + AddressLike, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedLogDescription, + TypedListener, + TypedContractMethod, +} from "./common"; + +export interface IL1ERC20BridgeInterface extends Interface { + getFunction( + nameOrSignature: + | "claimFailedDeposit" + | "deposit(address,address,uint256,uint256,uint256)" + | "deposit(address,address,uint256,uint256,uint256,address)" + | "depositAmount" + | "finalizeWithdrawal" + | "isWithdrawalFinalized" + | "l2Bridge" + | "l2TokenAddress" + | "l2TokenBeacon" + | "sharedBridge" + | "transferTokenToSharedBridge" + ): FunctionFragment; + + getEvent( + nameOrSignatureOrTopic: + | "ClaimedFailedDeposit" + | "DepositInitiated" + | "WithdrawalFinalized" + ): EventFragment; + + encodeFunctionData( + functionFragment: "claimFailedDeposit", + values: [ + AddressLike, + AddressLike, + BytesLike, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike[] + ] + ): string; + encodeFunctionData( + functionFragment: "deposit(address,address,uint256,uint256,uint256)", + values: [AddressLike, AddressLike, BigNumberish, BigNumberish, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "deposit(address,address,uint256,uint256,uint256,address)", + values: [ + AddressLike, + AddressLike, + BigNumberish, + BigNumberish, + BigNumberish, + AddressLike + ] + ): string; + encodeFunctionData( + functionFragment: "depositAmount", + values: [AddressLike, AddressLike, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "finalizeWithdrawal", + values: [BigNumberish, BigNumberish, BigNumberish, BytesLike, BytesLike[]] + ): string; + encodeFunctionData( + functionFragment: "isWithdrawalFinalized", + values: [BigNumberish, BigNumberish] + ): string; + encodeFunctionData(functionFragment: "l2Bridge", values?: undefined): string; + encodeFunctionData( + functionFragment: "l2TokenAddress", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "l2TokenBeacon", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "sharedBridge", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "transferTokenToSharedBridge", + values: [AddressLike, BigNumberish] + ): string; + + decodeFunctionResult( + functionFragment: "claimFailedDeposit", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "deposit(address,address,uint256,uint256,uint256)", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "deposit(address,address,uint256,uint256,uint256,address)", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "depositAmount", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "finalizeWithdrawal", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "isWithdrawalFinalized", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "l2Bridge", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "l2TokenAddress", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "l2TokenBeacon", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "sharedBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "transferTokenToSharedBridge", + data: BytesLike + ): Result; +} + +export namespace ClaimedFailedDepositEvent { + export type InputTuple = [ + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [to: string, l1Token: string, amount: bigint]; + export interface OutputObject { + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace DepositInitiatedEvent { + export type InputTuple = [ + l2DepositTxHash: BytesLike, + from: AddressLike, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + l2DepositTxHash: string, + from: string, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + l2DepositTxHash: string; + from: string; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace WithdrawalFinalizedEvent { + export type InputTuple = [ + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [to: string, l1Token: string, amount: bigint]; + export interface OutputObject { + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export interface IL1ERC20Bridge extends BaseContract { + connect(runner?: ContractRunner | null): IL1ERC20Bridge; + waitForDeployment(): Promise; + + interface: IL1ERC20BridgeInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + claimFailedDeposit: TypedContractMethod< + [ + _depositSender: AddressLike, + _l1Token: AddressLike, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + + "deposit(address,address,uint256,uint256,uint256)": TypedContractMethod< + [ + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish + ], + [string], + "payable" + >; + + "deposit(address,address,uint256,uint256,uint256,address)": TypedContractMethod< + [ + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish, + _refundRecipient: AddressLike + ], + [string], + "payable" + >; + + depositAmount: TypedContractMethod< + [_account: AddressLike, _l1Token: AddressLike, _depositL2TxHash: BytesLike], + [bigint], + "nonpayable" + >; + + finalizeWithdrawal: TypedContractMethod< + [ + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + + isWithdrawalFinalized: TypedContractMethod< + [_l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish], + [boolean], + "view" + >; + + l2Bridge: TypedContractMethod<[], [string], "view">; + + l2TokenAddress: TypedContractMethod< + [_l1Token: AddressLike], + [string], + "view" + >; + + l2TokenBeacon: TypedContractMethod<[], [string], "view">; + + sharedBridge: TypedContractMethod<[], [string], "view">; + + transferTokenToSharedBridge: TypedContractMethod< + [_token: AddressLike, _amount: BigNumberish], + [void], + "nonpayable" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "claimFailedDeposit" + ): TypedContractMethod< + [ + _depositSender: AddressLike, + _l1Token: AddressLike, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "deposit(address,address,uint256,uint256,uint256)" + ): TypedContractMethod< + [ + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish + ], + [string], + "payable" + >; + getFunction( + nameOrSignature: "deposit(address,address,uint256,uint256,uint256,address)" + ): TypedContractMethod< + [ + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish, + _refundRecipient: AddressLike + ], + [string], + "payable" + >; + getFunction( + nameOrSignature: "depositAmount" + ): TypedContractMethod< + [_account: AddressLike, _l1Token: AddressLike, _depositL2TxHash: BytesLike], + [bigint], + "nonpayable" + >; + getFunction( + nameOrSignature: "finalizeWithdrawal" + ): TypedContractMethod< + [ + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "isWithdrawalFinalized" + ): TypedContractMethod< + [_l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "l2Bridge" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "l2TokenAddress" + ): TypedContractMethod<[_l1Token: AddressLike], [string], "view">; + getFunction( + nameOrSignature: "l2TokenBeacon" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "sharedBridge" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "transferTokenToSharedBridge" + ): TypedContractMethod< + [_token: AddressLike, _amount: BigNumberish], + [void], + "nonpayable" + >; + + getEvent( + key: "ClaimedFailedDeposit" + ): TypedContractEvent< + ClaimedFailedDepositEvent.InputTuple, + ClaimedFailedDepositEvent.OutputTuple, + ClaimedFailedDepositEvent.OutputObject + >; + getEvent( + key: "DepositInitiated" + ): TypedContractEvent< + DepositInitiatedEvent.InputTuple, + DepositInitiatedEvent.OutputTuple, + DepositInitiatedEvent.OutputObject + >; + getEvent( + key: "WithdrawalFinalized" + ): TypedContractEvent< + WithdrawalFinalizedEvent.InputTuple, + WithdrawalFinalizedEvent.OutputTuple, + WithdrawalFinalizedEvent.OutputObject + >; + + filters: { + "ClaimedFailedDeposit(address,address,uint256)": TypedContractEvent< + ClaimedFailedDepositEvent.InputTuple, + ClaimedFailedDepositEvent.OutputTuple, + ClaimedFailedDepositEvent.OutputObject + >; + ClaimedFailedDeposit: TypedContractEvent< + ClaimedFailedDepositEvent.InputTuple, + ClaimedFailedDepositEvent.OutputTuple, + ClaimedFailedDepositEvent.OutputObject + >; + + "DepositInitiated(bytes32,address,address,address,uint256)": TypedContractEvent< + DepositInitiatedEvent.InputTuple, + DepositInitiatedEvent.OutputTuple, + DepositInitiatedEvent.OutputObject + >; + DepositInitiated: TypedContractEvent< + DepositInitiatedEvent.InputTuple, + DepositInitiatedEvent.OutputTuple, + DepositInitiatedEvent.OutputObject + >; + + "WithdrawalFinalized(address,address,uint256)": TypedContractEvent< + WithdrawalFinalizedEvent.InputTuple, + WithdrawalFinalizedEvent.OutputTuple, + WithdrawalFinalizedEvent.OutputObject + >; + WithdrawalFinalized: TypedContractEvent< + WithdrawalFinalizedEvent.InputTuple, + WithdrawalFinalizedEvent.OutputTuple, + WithdrawalFinalizedEvent.OutputObject + >; + }; +} diff --git a/src/typechain/IL1SharedBridge.ts b/src/typechain/IL1SharedBridge.ts new file mode 100644 index 00000000..72fc5872 --- /dev/null +++ b/src/typechain/IL1SharedBridge.ts @@ -0,0 +1,844 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + EventFragment, + AddressLike, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedLogDescription, + TypedListener, + TypedContractMethod, +} from "./common"; + +export type L2TransactionRequestTwoBridgesInnerStruct = { + magicValue: BytesLike; + l2Contract: AddressLike; + l2Calldata: BytesLike; + factoryDeps: BytesLike[]; + txDataHash: BytesLike; +}; + +export type L2TransactionRequestTwoBridgesInnerStructOutput = [ + magicValue: string, + l2Contract: string, + l2Calldata: string, + factoryDeps: string[], + txDataHash: string +] & { + magicValue: string; + l2Contract: string; + l2Calldata: string; + factoryDeps: string[]; + txDataHash: string; +}; + +export interface IL1SharedBridgeInterface extends Interface { + getFunction( + nameOrSignature: + | "bridgehub" + | "bridgehubConfirmL2Transaction" + | "bridgehubDeposit" + | "bridgehubDepositBaseToken" + | "claimFailedDeposit" + | "claimFailedDepositLegacyErc20Bridge" + | "depositHappened" + | "depositLegacyErc20Bridge" + | "finalizeWithdrawal" + | "finalizeWithdrawalLegacyErc20Bridge" + | "isWithdrawalFinalized" + | "l1WethAddress" + | "l2BridgeAddress" + | "legacyBridge" + | "receiveEth" + | "setEraFirstPostUpgradeBatch" + ): FunctionFragment; + + getEvent( + nameOrSignatureOrTopic: + | "BridgehubDepositBaseTokenInitiated" + | "BridgehubDepositFinalized" + | "BridgehubDepositInitiated" + | "ClaimedFailedDepositSharedBridge" + | "LegacyDepositInitiated" + | "WithdrawalFinalizedSharedBridge" + ): EventFragment; + + encodeFunctionData(functionFragment: "bridgehub", values?: undefined): string; + encodeFunctionData( + functionFragment: "bridgehubConfirmL2Transaction", + values: [BigNumberish, BytesLike, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "bridgehubDeposit", + values: [BigNumberish, AddressLike, BigNumberish, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "bridgehubDepositBaseToken", + values: [BigNumberish, AddressLike, AddressLike, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "claimFailedDeposit", + values: [ + BigNumberish, + AddressLike, + AddressLike, + BigNumberish, + BytesLike, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike[] + ] + ): string; + encodeFunctionData( + functionFragment: "claimFailedDepositLegacyErc20Bridge", + values: [ + AddressLike, + AddressLike, + BigNumberish, + BytesLike, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike[] + ] + ): string; + encodeFunctionData( + functionFragment: "depositHappened", + values: [BigNumberish, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "depositLegacyErc20Bridge", + values: [ + AddressLike, + AddressLike, + AddressLike, + BigNumberish, + BigNumberish, + BigNumberish, + AddressLike + ] + ): string; + encodeFunctionData( + functionFragment: "finalizeWithdrawal", + values: [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike, + BytesLike[] + ] + ): string; + encodeFunctionData( + functionFragment: "finalizeWithdrawalLegacyErc20Bridge", + values: [BigNumberish, BigNumberish, BigNumberish, BytesLike, BytesLike[]] + ): string; + encodeFunctionData( + functionFragment: "isWithdrawalFinalized", + values: [BigNumberish, BigNumberish, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "l1WethAddress", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "l2BridgeAddress", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "legacyBridge", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "receiveEth", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "setEraFirstPostUpgradeBatch", + values: [BigNumberish] + ): string; + + decodeFunctionResult(functionFragment: "bridgehub", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "bridgehubConfirmL2Transaction", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "bridgehubDeposit", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "bridgehubDepositBaseToken", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "claimFailedDeposit", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "claimFailedDepositLegacyErc20Bridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "depositHappened", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "depositLegacyErc20Bridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "finalizeWithdrawal", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "finalizeWithdrawalLegacyErc20Bridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "isWithdrawalFinalized", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "l1WethAddress", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "l2BridgeAddress", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "legacyBridge", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "receiveEth", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "setEraFirstPostUpgradeBatch", + data: BytesLike + ): Result; +} + +export namespace BridgehubDepositBaseTokenInitiatedEvent { + export type InputTuple = [ + chainId: BigNumberish, + from: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + from: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + from: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace BridgehubDepositFinalizedEvent { + export type InputTuple = [ + chainId: BigNumberish, + txDataHash: BytesLike, + l2DepositTxHash: BytesLike + ]; + export type OutputTuple = [ + chainId: bigint, + txDataHash: string, + l2DepositTxHash: string + ]; + export interface OutputObject { + chainId: bigint; + txDataHash: string; + l2DepositTxHash: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace BridgehubDepositInitiatedEvent { + export type InputTuple = [ + chainId: BigNumberish, + txDataHash: BytesLike, + from: AddressLike, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + txDataHash: string, + from: string, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + txDataHash: string; + from: string; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace ClaimedFailedDepositSharedBridgeEvent { + export type InputTuple = [ + chainId: BigNumberish, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace LegacyDepositInitiatedEvent { + export type InputTuple = [ + chainId: BigNumberish, + l2DepositTxHash: BytesLike, + from: AddressLike, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + l2DepositTxHash: string, + from: string, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + l2DepositTxHash: string; + from: string; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace WithdrawalFinalizedSharedBridgeEvent { + export type InputTuple = [ + chainId: BigNumberish, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export interface IL1SharedBridge extends BaseContract { + connect(runner?: ContractRunner | null): IL1SharedBridge; + waitForDeployment(): Promise; + + interface: IL1SharedBridgeInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + bridgehub: TypedContractMethod<[], [string], "view">; + + bridgehubConfirmL2Transaction: TypedContractMethod< + [_chainId: BigNumberish, _txDataHash: BytesLike, _txHash: BytesLike], + [void], + "nonpayable" + >; + + bridgehubDeposit: TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l2Value: BigNumberish, + _data: BytesLike + ], + [L2TransactionRequestTwoBridgesInnerStructOutput], + "payable" + >; + + bridgehubDepositBaseToken: TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish + ], + [void], + "payable" + >; + + claimFailedDeposit: TypedContractMethod< + [ + _chainId: BigNumberish, + _depositSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + + claimFailedDepositLegacyErc20Bridge: TypedContractMethod< + [ + _depositSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + + depositHappened: TypedContractMethod< + [_chainId: BigNumberish, _l2TxHash: BytesLike], + [string], + "view" + >; + + depositLegacyErc20Bridge: TypedContractMethod< + [ + _msgSender: AddressLike, + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish, + _refundRecipient: AddressLike + ], + [string], + "payable" + >; + + finalizeWithdrawal: TypedContractMethod< + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + + finalizeWithdrawalLegacyErc20Bridge: TypedContractMethod< + [ + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [ + [string, string, bigint] & { + l1Receiver: string; + l1Token: string; + amount: bigint; + } + ], + "nonpayable" + >; + + isWithdrawalFinalized: TypedContractMethod< + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish + ], + [boolean], + "view" + >; + + l1WethAddress: TypedContractMethod<[], [string], "view">; + + l2BridgeAddress: TypedContractMethod< + [_chainId: BigNumberish], + [string], + "view" + >; + + legacyBridge: TypedContractMethod<[], [string], "view">; + + receiveEth: TypedContractMethod<[_chainId: BigNumberish], [void], "payable">; + + setEraFirstPostUpgradeBatch: TypedContractMethod< + [_eraFirstPostUpgradeBatch: BigNumberish], + [void], + "nonpayable" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "bridgehub" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "bridgehubConfirmL2Transaction" + ): TypedContractMethod< + [_chainId: BigNumberish, _txDataHash: BytesLike, _txHash: BytesLike], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "bridgehubDeposit" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l2Value: BigNumberish, + _data: BytesLike + ], + [L2TransactionRequestTwoBridgesInnerStructOutput], + "payable" + >; + getFunction( + nameOrSignature: "bridgehubDepositBaseToken" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish + ], + [void], + "payable" + >; + getFunction( + nameOrSignature: "claimFailedDeposit" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _depositSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "claimFailedDepositLegacyErc20Bridge" + ): TypedContractMethod< + [ + _depositSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "depositHappened" + ): TypedContractMethod< + [_chainId: BigNumberish, _l2TxHash: BytesLike], + [string], + "view" + >; + getFunction( + nameOrSignature: "depositLegacyErc20Bridge" + ): TypedContractMethod< + [ + _msgSender: AddressLike, + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish, + _refundRecipient: AddressLike + ], + [string], + "payable" + >; + getFunction( + nameOrSignature: "finalizeWithdrawal" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "finalizeWithdrawalLegacyErc20Bridge" + ): TypedContractMethod< + [ + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [ + [string, string, bigint] & { + l1Receiver: string; + l1Token: string; + amount: bigint; + } + ], + "nonpayable" + >; + getFunction( + nameOrSignature: "isWithdrawalFinalized" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "l1WethAddress" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "l2BridgeAddress" + ): TypedContractMethod<[_chainId: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "legacyBridge" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "receiveEth" + ): TypedContractMethod<[_chainId: BigNumberish], [void], "payable">; + getFunction( + nameOrSignature: "setEraFirstPostUpgradeBatch" + ): TypedContractMethod< + [_eraFirstPostUpgradeBatch: BigNumberish], + [void], + "nonpayable" + >; + + getEvent( + key: "BridgehubDepositBaseTokenInitiated" + ): TypedContractEvent< + BridgehubDepositBaseTokenInitiatedEvent.InputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputObject + >; + getEvent( + key: "BridgehubDepositFinalized" + ): TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + getEvent( + key: "BridgehubDepositInitiated" + ): TypedContractEvent< + BridgehubDepositInitiatedEvent.InputTuple, + BridgehubDepositInitiatedEvent.OutputTuple, + BridgehubDepositInitiatedEvent.OutputObject + >; + getEvent( + key: "ClaimedFailedDepositSharedBridge" + ): TypedContractEvent< + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject + >; + getEvent( + key: "LegacyDepositInitiated" + ): TypedContractEvent< + LegacyDepositInitiatedEvent.InputTuple, + LegacyDepositInitiatedEvent.OutputTuple, + LegacyDepositInitiatedEvent.OutputObject + >; + getEvent( + key: "WithdrawalFinalizedSharedBridge" + ): TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject + >; + + filters: { + "BridgehubDepositBaseTokenInitiated(uint256,address,address,uint256)": TypedContractEvent< + BridgehubDepositBaseTokenInitiatedEvent.InputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputObject + >; + BridgehubDepositBaseTokenInitiated: TypedContractEvent< + BridgehubDepositBaseTokenInitiatedEvent.InputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputObject + >; + + "BridgehubDepositFinalized(uint256,bytes32,bytes32)": TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + BridgehubDepositFinalized: TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + + "BridgehubDepositInitiated(uint256,bytes32,address,address,address,uint256)": TypedContractEvent< + BridgehubDepositInitiatedEvent.InputTuple, + BridgehubDepositInitiatedEvent.OutputTuple, + BridgehubDepositInitiatedEvent.OutputObject + >; + BridgehubDepositInitiated: TypedContractEvent< + BridgehubDepositInitiatedEvent.InputTuple, + BridgehubDepositInitiatedEvent.OutputTuple, + BridgehubDepositInitiatedEvent.OutputObject + >; + + "ClaimedFailedDepositSharedBridge(uint256,address,address,uint256)": TypedContractEvent< + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject + >; + ClaimedFailedDepositSharedBridge: TypedContractEvent< + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject + >; + + "LegacyDepositInitiated(uint256,bytes32,address,address,address,uint256)": TypedContractEvent< + LegacyDepositInitiatedEvent.InputTuple, + LegacyDepositInitiatedEvent.OutputTuple, + LegacyDepositInitiatedEvent.OutputObject + >; + LegacyDepositInitiated: TypedContractEvent< + LegacyDepositInitiatedEvent.InputTuple, + LegacyDepositInitiatedEvent.OutputTuple, + LegacyDepositInitiatedEvent.OutputObject + >; + + "WithdrawalFinalizedSharedBridge(uint256,address,address,uint256)": TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject + >; + WithdrawalFinalizedSharedBridge: TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject + >; + }; +} diff --git a/src/typechain/ITestnetERC20Token.ts b/src/typechain/ITestnetERC20Token.ts new file mode 100644 index 00000000..d13cc526 --- /dev/null +++ b/src/typechain/ITestnetERC20Token.ts @@ -0,0 +1,104 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + AddressLike, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedListener, + TypedContractMethod, +} from "./common"; + +export interface ITestnetERC20TokenInterface extends Interface { + getFunction(nameOrSignature: "decimals" | "mint"): FunctionFragment; + + encodeFunctionData(functionFragment: "decimals", values?: undefined): string; + encodeFunctionData( + functionFragment: "mint", + values: [AddressLike, BigNumberish] + ): string; + + decodeFunctionResult(functionFragment: "decimals", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "mint", data: BytesLike): Result; +} + +export interface ITestnetERC20Token extends BaseContract { + connect(runner?: ContractRunner | null): ITestnetERC20Token; + waitForDeployment(): Promise; + + interface: ITestnetERC20TokenInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + decimals: TypedContractMethod<[], [bigint], "nonpayable">; + + mint: TypedContractMethod< + [_to: AddressLike, _amount: BigNumberish], + [boolean], + "nonpayable" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "decimals" + ): TypedContractMethod<[], [bigint], "nonpayable">; + getFunction( + nameOrSignature: "mint" + ): TypedContractMethod< + [_to: AddressLike, _amount: BigNumberish], + [boolean], + "nonpayable" + >; + + filters: {}; +} diff --git a/src/typechain/IZkSync.ts b/src/typechain/IZkSyncStateTransition.ts similarity index 71% rename from src/typechain/IZkSync.ts rename to src/typechain/IZkSyncStateTransition.ts index c33ca9bb..2675853b 100644 --- a/src/typechain/IZkSync.ts +++ b/src/typechain/IZkSyncStateTransition.ts @@ -23,6 +23,120 @@ import type { TypedContractMethod, } from "./common"; +export type FeeParamsStruct = { + pubdataPricingMode: BigNumberish; + batchOverheadL1Gas: BigNumberish; + maxPubdataPerBatch: BigNumberish; + maxL2GasPerBatch: BigNumberish; + priorityTxMaxPubdata: BigNumberish; + minimalL2GasPrice: BigNumberish; +}; + +export type FeeParamsStructOutput = [ + pubdataPricingMode: bigint, + batchOverheadL1Gas: bigint, + maxPubdataPerBatch: bigint, + maxL2GasPerBatch: bigint, + priorityTxMaxPubdata: bigint, + minimalL2GasPrice: bigint +] & { + pubdataPricingMode: bigint; + batchOverheadL1Gas: bigint; + maxPubdataPerBatch: bigint; + maxL2GasPerBatch: bigint; + priorityTxMaxPubdata: bigint; + minimalL2GasPrice: bigint; +}; + +export type L2CanonicalTransactionStruct = { + txType: BigNumberish; + from: BigNumberish; + to: BigNumberish; + gasLimit: BigNumberish; + gasPerPubdataByteLimit: BigNumberish; + maxFeePerGas: BigNumberish; + maxPriorityFeePerGas: BigNumberish; + paymaster: BigNumberish; + nonce: BigNumberish; + value: BigNumberish; + reserved: [BigNumberish, BigNumberish, BigNumberish, BigNumberish]; + data: BytesLike; + signature: BytesLike; + factoryDeps: BigNumberish[]; + paymasterInput: BytesLike; + reservedDynamic: BytesLike; +}; + +export type L2CanonicalTransactionStructOutput = [ + txType: bigint, + from: bigint, + to: bigint, + gasLimit: bigint, + gasPerPubdataByteLimit: bigint, + maxFeePerGas: bigint, + maxPriorityFeePerGas: bigint, + paymaster: bigint, + nonce: bigint, + value: bigint, + reserved: [bigint, bigint, bigint, bigint], + data: string, + signature: string, + factoryDeps: bigint[], + paymasterInput: string, + reservedDynamic: string +] & { + txType: bigint; + from: bigint; + to: bigint; + gasLimit: bigint; + gasPerPubdataByteLimit: bigint; + maxFeePerGas: bigint; + maxPriorityFeePerGas: bigint; + paymaster: bigint; + nonce: bigint; + value: bigint; + reserved: [bigint, bigint, bigint, bigint]; + data: string; + signature: string; + factoryDeps: bigint[]; + paymasterInput: string; + reservedDynamic: string; +}; + +export type BridgehubL2TransactionRequestStruct = { + sender: AddressLike; + contractL2: AddressLike; + mintValue: BigNumberish; + l2Value: BigNumberish; + l2Calldata: BytesLike; + l2GasLimit: BigNumberish; + l2GasPerPubdataByteLimit: BigNumberish; + factoryDeps: BytesLike[]; + refundRecipient: AddressLike; +}; + +export type BridgehubL2TransactionRequestStructOutput = [ + sender: string, + contractL2: string, + mintValue: bigint, + l2Value: bigint, + l2Calldata: string, + l2GasLimit: bigint, + l2GasPerPubdataByteLimit: bigint, + factoryDeps: string[], + refundRecipient: string +] & { + sender: string; + contractL2: string; + mintValue: bigint; + l2Value: bigint; + l2Calldata: string; + l2GasLimit: bigint; + l2GasPerPubdataByteLimit: bigint; + factoryDeps: string[]; + refundRecipient: string; +}; + export type VerifierParamsStruct = { recursionNodeLevelVkHash: BytesLike; recursionLeafLevelVkHash: BytesLike; @@ -125,63 +239,6 @@ export declare namespace Diamond { }; } -export declare namespace IMailbox { - export type L2CanonicalTransactionStruct = { - txType: BigNumberish; - from: BigNumberish; - to: BigNumberish; - gasLimit: BigNumberish; - gasPerPubdataByteLimit: BigNumberish; - maxFeePerGas: BigNumberish; - maxPriorityFeePerGas: BigNumberish; - paymaster: BigNumberish; - nonce: BigNumberish; - value: BigNumberish; - reserved: [BigNumberish, BigNumberish, BigNumberish, BigNumberish]; - data: BytesLike; - signature: BytesLike; - factoryDeps: BigNumberish[]; - paymasterInput: BytesLike; - reservedDynamic: BytesLike; - }; - - export type L2CanonicalTransactionStructOutput = [ - txType: bigint, - from: bigint, - to: bigint, - gasLimit: bigint, - gasPerPubdataByteLimit: bigint, - maxFeePerGas: bigint, - maxPriorityFeePerGas: bigint, - paymaster: bigint, - nonce: bigint, - value: bigint, - reserved: [bigint, bigint, bigint, bigint], - data: string, - signature: string, - factoryDeps: bigint[], - paymasterInput: string, - reservedDynamic: string - ] & { - txType: bigint; - from: bigint; - to: bigint; - gasLimit: bigint; - gasPerPubdataByteLimit: bigint; - maxFeePerGas: bigint; - maxPriorityFeePerGas: bigint; - paymaster: bigint; - nonce: bigint; - value: bigint; - reserved: [bigint, bigint, bigint, bigint]; - data: string; - signature: string; - factoryDeps: bigint[]; - paymasterInput: string; - reservedDynamic: string; - }; -} - export declare namespace IExecutor { export type StoredBatchInfoStruct = { batchNumber: BigNumberish; @@ -224,7 +281,7 @@ export declare namespace IExecutor { bootloaderHeapInitialContentsHash: BytesLike; eventsQueueStateHash: BytesLike; systemLogs: BytesLike; - totalL2ToL1Pubdata: BytesLike; + pubdataCommitments: BytesLike; }; export type CommitBatchInfoStructOutput = [ @@ -237,7 +294,7 @@ export declare namespace IExecutor { bootloaderHeapInitialContentsHash: string, eventsQueueStateHash: string, systemLogs: string, - totalL2ToL1Pubdata: string + pubdataCommitments: string ] & { batchNumber: bigint; timestamp: bigint; @@ -248,7 +305,7 @@ export declare namespace IExecutor { bootloaderHeapInitialContentsHash: string; eventsQueueStateHash: string; systemLogs: string; - totalL2ToL1Pubdata: string; + pubdataCommitments: string; }; export type ProofInputStruct = { @@ -271,13 +328,18 @@ export declare namespace IGetters { }; } -export interface IZkSyncInterface extends Interface { +export interface IZkSyncStateTransitionInterface extends Interface { getFunction( nameOrSignature: | "acceptAdmin" - | "acceptGovernor" + | "baseTokenGasPriceMultiplierDenominator" + | "baseTokenGasPriceMultiplierNominator" + | "bridgehubRequestL2Transaction" + | "changeFeeParams" | "commitBatches" + | "commitBatchesSharedBridge" | "executeBatches" + | "executeBatchesSharedBridge" | "executeUpgrade" | "facetAddress" | "facetAddresses" @@ -285,17 +347,22 @@ export interface IZkSyncInterface extends Interface { | "facets" | "finalizeEthWithdrawal" | "freezeDiamond" + | "getAdmin" + | "getBaseToken" + | "getBaseTokenBridge" + | "getBridgehub" | "getFirstUnprocessedPriorityTx" - | "getGovernor" | "getL2BootloaderBytecodeHash" | "getL2DefaultAccountBytecodeHash" | "getL2SystemContractsUpgradeBatchNumber" | "getL2SystemContractsUpgradeTxHash" | "getName" - | "getPendingGovernor" + | "getPendingAdmin" | "getPriorityQueueSize" | "getPriorityTxMaxGasLimit" | "getProtocolVersion" + | "getPubdataPricingMode" + | "getStateTransitionManager" | "getTotalBatchesCommitted" | "getTotalBatchesExecuted" | "getTotalBatchesVerified" @@ -311,18 +378,24 @@ export interface IZkSyncInterface extends Interface { | "l2TransactionBaseCost" | "priorityQueueFrontOperation" | "proveBatches" + | "proveBatchesSharedBridge" | "proveL1ToL2TransactionStatus" | "proveL2LogInclusion" | "proveL2MessageInclusion" | "requestL2Transaction" | "revertBatches" + | "revertBatchesSharedBridge" | "setPendingAdmin" - | "setPendingGovernor" | "setPorterAvailability" | "setPriorityTxMaxGasLimit" + | "setTokenMultiplier" + | "setTransactionFilterer" | "setValidator" + | "setValidiumMode" | "storedBatchHash" + | "transferEthToSharedBridge" | "unfreezeDiamond" + | "upgradeChainFromVersion" ): FunctionFragment; getEvent( @@ -336,13 +409,16 @@ export interface IZkSyncInterface extends Interface { | "Freeze" | "IsPorterAvailableStatusUpdate" | "NewAdmin" - | "NewGovernor" + | "NewBaseTokenMultiplier" + | "NewFeeParams" | "NewPendingAdmin" - | "NewPendingGovernor" | "NewPriorityRequest" | "NewPriorityTxMaxGasLimit" + | "NewTransactionFilterer" + | "ProposeTransparentUpgrade" | "Unfreeze" | "ValidatorStatusUpdate" + | "ValidiumModeStatusUpdate" ): EventFragment; encodeFunctionData( @@ -350,17 +426,41 @@ export interface IZkSyncInterface extends Interface { values?: undefined ): string; encodeFunctionData( - functionFragment: "acceptGovernor", + functionFragment: "baseTokenGasPriceMultiplierDenominator", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "baseTokenGasPriceMultiplierNominator", values?: undefined ): string; + encodeFunctionData( + functionFragment: "bridgehubRequestL2Transaction", + values: [BridgehubL2TransactionRequestStruct] + ): string; + encodeFunctionData( + functionFragment: "changeFeeParams", + values: [FeeParamsStruct] + ): string; encodeFunctionData( functionFragment: "commitBatches", values: [IExecutor.StoredBatchInfoStruct, IExecutor.CommitBatchInfoStruct[]] ): string; + encodeFunctionData( + functionFragment: "commitBatchesSharedBridge", + values: [ + BigNumberish, + IExecutor.StoredBatchInfoStruct, + IExecutor.CommitBatchInfoStruct[] + ] + ): string; encodeFunctionData( functionFragment: "executeBatches", values: [IExecutor.StoredBatchInfoStruct[]] ): string; + encodeFunctionData( + functionFragment: "executeBatchesSharedBridge", + values: [BigNumberish, IExecutor.StoredBatchInfoStruct[]] + ): string; encodeFunctionData( functionFragment: "executeUpgrade", values: [Diamond.DiamondCutDataStruct] @@ -386,12 +486,21 @@ export interface IZkSyncInterface extends Interface { functionFragment: "freezeDiamond", values?: undefined ): string; + encodeFunctionData(functionFragment: "getAdmin", values?: undefined): string; encodeFunctionData( - functionFragment: "getFirstUnprocessedPriorityTx", + functionFragment: "getBaseToken", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getBaseTokenBridge", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getBridgehub", values?: undefined ): string; encodeFunctionData( - functionFragment: "getGovernor", + functionFragment: "getFirstUnprocessedPriorityTx", values?: undefined ): string; encodeFunctionData( @@ -412,7 +521,7 @@ export interface IZkSyncInterface extends Interface { ): string; encodeFunctionData(functionFragment: "getName", values?: undefined): string; encodeFunctionData( - functionFragment: "getPendingGovernor", + functionFragment: "getPendingAdmin", values?: undefined ): string; encodeFunctionData( @@ -427,6 +536,14 @@ export interface IZkSyncInterface extends Interface { functionFragment: "getProtocolVersion", values?: undefined ): string; + encodeFunctionData( + functionFragment: "getPubdataPricingMode", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getStateTransitionManager", + values?: undefined + ): string; encodeFunctionData( functionFragment: "getTotalBatchesCommitted", values?: undefined @@ -491,6 +608,15 @@ export interface IZkSyncInterface extends Interface { IExecutor.ProofInputStruct ] ): string; + encodeFunctionData( + functionFragment: "proveBatchesSharedBridge", + values: [ + BigNumberish, + IExecutor.StoredBatchInfoStruct, + IExecutor.StoredBatchInfoStruct[], + IExecutor.ProofInputStruct + ] + ): string; encodeFunctionData( functionFragment: "proveL1ToL2TransactionStatus", values: [ @@ -527,11 +653,11 @@ export interface IZkSyncInterface extends Interface { values: [BigNumberish] ): string; encodeFunctionData( - functionFragment: "setPendingAdmin", - values: [AddressLike] + functionFragment: "revertBatchesSharedBridge", + values: [BigNumberish, BigNumberish] ): string; encodeFunctionData( - functionFragment: "setPendingGovernor", + functionFragment: "setPendingAdmin", values: [AddressLike] ): string; encodeFunctionData( @@ -542,35 +668,75 @@ export interface IZkSyncInterface extends Interface { functionFragment: "setPriorityTxMaxGasLimit", values: [BigNumberish] ): string; + encodeFunctionData( + functionFragment: "setTokenMultiplier", + values: [BigNumberish, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "setTransactionFilterer", + values: [AddressLike] + ): string; encodeFunctionData( functionFragment: "setValidator", values: [AddressLike, boolean] ): string; + encodeFunctionData( + functionFragment: "setValidiumMode", + values: [BigNumberish] + ): string; encodeFunctionData( functionFragment: "storedBatchHash", values: [BigNumberish] ): string; + encodeFunctionData( + functionFragment: "transferEthToSharedBridge", + values?: undefined + ): string; encodeFunctionData( functionFragment: "unfreezeDiamond", values?: undefined ): string; + encodeFunctionData( + functionFragment: "upgradeChainFromVersion", + values: [BigNumberish, Diamond.DiamondCutDataStruct] + ): string; decodeFunctionResult( functionFragment: "acceptAdmin", data: BytesLike ): Result; decodeFunctionResult( - functionFragment: "acceptGovernor", + functionFragment: "baseTokenGasPriceMultiplierDenominator", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "baseTokenGasPriceMultiplierNominator", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "bridgehubRequestL2Transaction", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "changeFeeParams", data: BytesLike ): Result; decodeFunctionResult( functionFragment: "commitBatches", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "commitBatchesSharedBridge", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "executeBatches", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "executeBatchesSharedBridge", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "executeUpgrade", data: BytesLike @@ -596,12 +762,21 @@ export interface IZkSyncInterface extends Interface { functionFragment: "freezeDiamond", data: BytesLike ): Result; + decodeFunctionResult(functionFragment: "getAdmin", data: BytesLike): Result; decodeFunctionResult( - functionFragment: "getFirstUnprocessedPriorityTx", + functionFragment: "getBaseToken", data: BytesLike ): Result; decodeFunctionResult( - functionFragment: "getGovernor", + functionFragment: "getBaseTokenBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getBridgehub", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getFirstUnprocessedPriorityTx", data: BytesLike ): Result; decodeFunctionResult( @@ -622,7 +797,7 @@ export interface IZkSyncInterface extends Interface { ): Result; decodeFunctionResult(functionFragment: "getName", data: BytesLike): Result; decodeFunctionResult( - functionFragment: "getPendingGovernor", + functionFragment: "getPendingAdmin", data: BytesLike ): Result; decodeFunctionResult( @@ -637,6 +812,14 @@ export interface IZkSyncInterface extends Interface { functionFragment: "getProtocolVersion", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "getPubdataPricingMode", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getStateTransitionManager", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "getTotalBatchesCommitted", data: BytesLike @@ -697,6 +880,10 @@ export interface IZkSyncInterface extends Interface { functionFragment: "proveBatches", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "proveBatchesSharedBridge", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "proveL1ToL2TransactionStatus", data: BytesLike @@ -718,11 +905,11 @@ export interface IZkSyncInterface extends Interface { data: BytesLike ): Result; decodeFunctionResult( - functionFragment: "setPendingAdmin", + functionFragment: "revertBatchesSharedBridge", data: BytesLike ): Result; decodeFunctionResult( - functionFragment: "setPendingGovernor", + functionFragment: "setPendingAdmin", data: BytesLike ): Result; decodeFunctionResult( @@ -733,18 +920,38 @@ export interface IZkSyncInterface extends Interface { functionFragment: "setPriorityTxMaxGasLimit", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "setTokenMultiplier", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setTransactionFilterer", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "setValidator", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "setValidiumMode", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "storedBatchHash", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "transferEthToSharedBridge", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "unfreezeDiamond", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "upgradeChainFromVersion", + data: BytesLike + ): Result; } export namespace BlockCommitEvent { @@ -892,12 +1099,24 @@ export namespace NewAdminEvent { export type LogDescription = TypedLogDescription; } -export namespace NewGovernorEvent { - export type InputTuple = [oldGovernor: AddressLike, newGovernor: AddressLike]; - export type OutputTuple = [oldGovernor: string, newGovernor: string]; +export namespace NewBaseTokenMultiplierEvent { + export type InputTuple = [ + oldNominator: BigNumberish, + oldDenominator: BigNumberish, + newNominator: BigNumberish, + newDenominator: BigNumberish + ]; + export type OutputTuple = [ + oldNominator: bigint, + oldDenominator: bigint, + newNominator: bigint, + newDenominator: bigint + ]; export interface OutputObject { - oldGovernor: string; - newGovernor: string; + oldNominator: bigint; + oldDenominator: bigint; + newNominator: bigint; + newDenominator: bigint; } export type Event = TypedContractEvent; export type Filter = TypedDeferredTopicFilter; @@ -905,15 +1124,18 @@ export namespace NewGovernorEvent { export type LogDescription = TypedLogDescription; } -export namespace NewPendingAdminEvent { +export namespace NewFeeParamsEvent { export type InputTuple = [ - oldPendingAdmin: AddressLike, - newPendingAdmin: AddressLike + oldFeeParams: FeeParamsStruct, + newFeeParams: FeeParamsStruct + ]; + export type OutputTuple = [ + oldFeeParams: FeeParamsStructOutput, + newFeeParams: FeeParamsStructOutput ]; - export type OutputTuple = [oldPendingAdmin: string, newPendingAdmin: string]; export interface OutputObject { - oldPendingAdmin: string; - newPendingAdmin: string; + oldFeeParams: FeeParamsStructOutput; + newFeeParams: FeeParamsStructOutput; } export type Event = TypedContractEvent; export type Filter = TypedDeferredTopicFilter; @@ -921,18 +1143,15 @@ export namespace NewPendingAdminEvent { export type LogDescription = TypedLogDescription; } -export namespace NewPendingGovernorEvent { +export namespace NewPendingAdminEvent { export type InputTuple = [ - oldPendingGovernor: AddressLike, - newPendingGovernor: AddressLike - ]; - export type OutputTuple = [ - oldPendingGovernor: string, - newPendingGovernor: string + oldPendingAdmin: AddressLike, + newPendingAdmin: AddressLike ]; + export type OutputTuple = [oldPendingAdmin: string, newPendingAdmin: string]; export interface OutputObject { - oldPendingGovernor: string; - newPendingGovernor: string; + oldPendingAdmin: string; + newPendingAdmin: string; } export type Event = TypedContractEvent; export type Filter = TypedDeferredTopicFilter; @@ -945,21 +1164,21 @@ export namespace NewPriorityRequestEvent { txId: BigNumberish, txHash: BytesLike, expirationTimestamp: BigNumberish, - transaction: IMailbox.L2CanonicalTransactionStruct, + transaction: L2CanonicalTransactionStruct, factoryDeps: BytesLike[] ]; export type OutputTuple = [ txId: bigint, txHash: string, expirationTimestamp: bigint, - transaction: IMailbox.L2CanonicalTransactionStructOutput, + transaction: L2CanonicalTransactionStructOutput, factoryDeps: string[] ]; export interface OutputObject { txId: bigint; txHash: string; expirationTimestamp: bigint; - transaction: IMailbox.L2CanonicalTransactionStructOutput; + transaction: L2CanonicalTransactionStructOutput; factoryDeps: string[]; } export type Event = TypedContractEvent; @@ -987,6 +1206,47 @@ export namespace NewPriorityTxMaxGasLimitEvent { export type LogDescription = TypedLogDescription; } +export namespace NewTransactionFiltererEvent { + export type InputTuple = [ + oldTransactionFilterer: AddressLike, + newTransactionFilterer: AddressLike + ]; + export type OutputTuple = [ + oldTransactionFilterer: string, + newTransactionFilterer: string + ]; + export interface OutputObject { + oldTransactionFilterer: string; + newTransactionFilterer: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace ProposeTransparentUpgradeEvent { + export type InputTuple = [ + diamondCut: Diamond.DiamondCutDataStruct, + proposalId: BigNumberish, + proposalSalt: BytesLike + ]; + export type OutputTuple = [ + diamondCut: Diamond.DiamondCutDataStructOutput, + proposalId: bigint, + proposalSalt: string + ]; + export interface OutputObject { + diamondCut: Diamond.DiamondCutDataStructOutput; + proposalId: bigint; + proposalSalt: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + export namespace UnfreezeEvent { export type InputTuple = []; export type OutputTuple = []; @@ -1010,11 +1270,23 @@ export namespace ValidatorStatusUpdateEvent { export type LogDescription = TypedLogDescription; } -export interface IZkSync extends BaseContract { - connect(runner?: ContractRunner | null): IZkSync; +export namespace ValidiumModeStatusUpdateEvent { + export type InputTuple = [validiumMode: BigNumberish]; + export type OutputTuple = [validiumMode: bigint]; + export interface OutputObject { + validiumMode: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export interface IZkSyncStateTransition extends BaseContract { + connect(runner?: ContractRunner | null): IZkSyncStateTransition; waitForDeployment(): Promise; - interface: IZkSyncInterface; + interface: IZkSyncStateTransitionInterface; queryFilter( event: TCEvent, @@ -1055,7 +1327,29 @@ export interface IZkSync extends BaseContract { acceptAdmin: TypedContractMethod<[], [void], "nonpayable">; - acceptGovernor: TypedContractMethod<[], [void], "nonpayable">; + baseTokenGasPriceMultiplierDenominator: TypedContractMethod< + [], + [bigint], + "view" + >; + + baseTokenGasPriceMultiplierNominator: TypedContractMethod< + [], + [bigint], + "view" + >; + + bridgehubRequestL2Transaction: TypedContractMethod< + [_request: BridgehubL2TransactionRequestStruct], + [string], + "payable" + >; + + changeFeeParams: TypedContractMethod< + [_newFeeParams: FeeParamsStruct], + [void], + "nonpayable" + >; commitBatches: TypedContractMethod< [ @@ -1066,12 +1360,28 @@ export interface IZkSync extends BaseContract { "nonpayable" >; + commitBatchesSharedBridge: TypedContractMethod< + [ + _chainId: BigNumberish, + _lastCommittedBatchData: IExecutor.StoredBatchInfoStruct, + _newBatchesData: IExecutor.CommitBatchInfoStruct[] + ], + [void], + "nonpayable" + >; + executeBatches: TypedContractMethod< [_batchesData: IExecutor.StoredBatchInfoStruct[]], [void], "nonpayable" >; + executeBatchesSharedBridge: TypedContractMethod< + [_chainId: BigNumberish, _batchesData: IExecutor.StoredBatchInfoStruct[]], + [void], + "nonpayable" + >; + executeUpgrade: TypedContractMethod< [_diamondCut: Diamond.DiamondCutDataStruct], [void], @@ -1104,9 +1414,15 @@ export interface IZkSync extends BaseContract { freezeDiamond: TypedContractMethod<[], [void], "nonpayable">; - getFirstUnprocessedPriorityTx: TypedContractMethod<[], [bigint], "view">; + getAdmin: TypedContractMethod<[], [string], "view">; + + getBaseToken: TypedContractMethod<[], [string], "view">; - getGovernor: TypedContractMethod<[], [string], "view">; + getBaseTokenBridge: TypedContractMethod<[], [string], "view">; + + getBridgehub: TypedContractMethod<[], [string], "view">; + + getFirstUnprocessedPriorityTx: TypedContractMethod<[], [bigint], "view">; getL2BootloaderBytecodeHash: TypedContractMethod<[], [string], "view">; @@ -1122,7 +1438,7 @@ export interface IZkSync extends BaseContract { getName: TypedContractMethod<[], [string], "view">; - getPendingGovernor: TypedContractMethod<[], [string], "view">; + getPendingAdmin: TypedContractMethod<[], [string], "view">; getPriorityQueueSize: TypedContractMethod<[], [bigint], "view">; @@ -1130,6 +1446,10 @@ export interface IZkSync extends BaseContract { getProtocolVersion: TypedContractMethod<[], [bigint], "view">; + getPubdataPricingMode: TypedContractMethod<[], [bigint], "view">; + + getStateTransitionManager: TypedContractMethod<[], [string], "view">; + getTotalBatchesCommitted: TypedContractMethod<[], [bigint], "view">; getTotalBatchesExecuted: TypedContractMethod<[], [bigint], "view">; @@ -1200,6 +1520,17 @@ export interface IZkSync extends BaseContract { "nonpayable" >; + proveBatchesSharedBridge: TypedContractMethod< + [ + _chainId: BigNumberish, + _prevBatch: IExecutor.StoredBatchInfoStruct, + _committedBatches: IExecutor.StoredBatchInfoStruct[], + _proof: IExecutor.ProofInputStruct + ], + [void], + "nonpayable" + >; + proveL1ToL2TransactionStatus: TypedContractMethod< [ _l2TxHash: BytesLike, @@ -1215,7 +1546,7 @@ export interface IZkSync extends BaseContract { proveL2LogInclusion: TypedContractMethod< [ - _l2BatchNumber: BigNumberish, + _batchNumber: BigNumberish, _index: BigNumberish, _log: L2LogStruct, _proof: BytesLike[] @@ -1226,7 +1557,7 @@ export interface IZkSync extends BaseContract { proveL2MessageInclusion: TypedContractMethod< [ - _l2BatchNumber: BigNumberish, + _batchNumber: BigNumberish, _index: BigNumberish, _message: L2MessageStruct, _proof: BytesLike[] @@ -1255,14 +1586,14 @@ export interface IZkSync extends BaseContract { "nonpayable" >; - setPendingAdmin: TypedContractMethod< - [_newPendingAdmin: AddressLike], + revertBatchesSharedBridge: TypedContractMethod< + [_chainId: BigNumberish, _newLastBatch: BigNumberish], [void], "nonpayable" >; - setPendingGovernor: TypedContractMethod< - [_newPendingGovernor: AddressLike], + setPendingAdmin: TypedContractMethod< + [_newPendingAdmin: AddressLike], [void], "nonpayable" >; @@ -1279,20 +1610,46 @@ export interface IZkSync extends BaseContract { "nonpayable" >; + setTokenMultiplier: TypedContractMethod< + [_nominator: BigNumberish, _denominator: BigNumberish], + [void], + "nonpayable" + >; + + setTransactionFilterer: TypedContractMethod< + [_transactionFilterer: AddressLike], + [void], + "nonpayable" + >; + setValidator: TypedContractMethod< [_validator: AddressLike, _active: boolean], [void], "nonpayable" >; + setValidiumMode: TypedContractMethod< + [_validiumMode: BigNumberish], + [void], + "nonpayable" + >; + storedBatchHash: TypedContractMethod< [_batchNumber: BigNumberish], [string], "view" >; + transferEthToSharedBridge: TypedContractMethod<[], [void], "nonpayable">; + unfreezeDiamond: TypedContractMethod<[], [void], "nonpayable">; + upgradeChainFromVersion: TypedContractMethod< + [_protocolVersion: BigNumberish, _cutData: Diamond.DiamondCutDataStruct], + [void], + "nonpayable" + >; + getFunction( key: string | FunctionFragment ): T; @@ -1301,8 +1658,25 @@ export interface IZkSync extends BaseContract { nameOrSignature: "acceptAdmin" ): TypedContractMethod<[], [void], "nonpayable">; getFunction( - nameOrSignature: "acceptGovernor" - ): TypedContractMethod<[], [void], "nonpayable">; + nameOrSignature: "baseTokenGasPriceMultiplierDenominator" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "baseTokenGasPriceMultiplierNominator" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "bridgehubRequestL2Transaction" + ): TypedContractMethod< + [_request: BridgehubL2TransactionRequestStruct], + [string], + "payable" + >; + getFunction( + nameOrSignature: "changeFeeParams" + ): TypedContractMethod< + [_newFeeParams: FeeParamsStruct], + [void], + "nonpayable" + >; getFunction( nameOrSignature: "commitBatches" ): TypedContractMethod< @@ -1313,6 +1687,17 @@ export interface IZkSync extends BaseContract { [void], "nonpayable" >; + getFunction( + nameOrSignature: "commitBatchesSharedBridge" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _lastCommittedBatchData: IExecutor.StoredBatchInfoStruct, + _newBatchesData: IExecutor.CommitBatchInfoStruct[] + ], + [void], + "nonpayable" + >; getFunction( nameOrSignature: "executeBatches" ): TypedContractMethod< @@ -1320,6 +1705,13 @@ export interface IZkSync extends BaseContract { [void], "nonpayable" >; + getFunction( + nameOrSignature: "executeBatchesSharedBridge" + ): TypedContractMethod< + [_chainId: BigNumberish, _batchesData: IExecutor.StoredBatchInfoStruct[]], + [void], + "nonpayable" + >; getFunction( nameOrSignature: "executeUpgrade" ): TypedContractMethod< @@ -1356,11 +1748,20 @@ export interface IZkSync extends BaseContract { nameOrSignature: "freezeDiamond" ): TypedContractMethod<[], [void], "nonpayable">; getFunction( - nameOrSignature: "getFirstUnprocessedPriorityTx" - ): TypedContractMethod<[], [bigint], "view">; + nameOrSignature: "getAdmin" + ): TypedContractMethod<[], [string], "view">; getFunction( - nameOrSignature: "getGovernor" + nameOrSignature: "getBaseToken" ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getBaseTokenBridge" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getBridgehub" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getFirstUnprocessedPriorityTx" + ): TypedContractMethod<[], [bigint], "view">; getFunction( nameOrSignature: "getL2BootloaderBytecodeHash" ): TypedContractMethod<[], [string], "view">; @@ -1377,7 +1778,7 @@ export interface IZkSync extends BaseContract { nameOrSignature: "getName" ): TypedContractMethod<[], [string], "view">; getFunction( - nameOrSignature: "getPendingGovernor" + nameOrSignature: "getPendingAdmin" ): TypedContractMethod<[], [string], "view">; getFunction( nameOrSignature: "getPriorityQueueSize" @@ -1388,6 +1789,12 @@ export interface IZkSync extends BaseContract { getFunction( nameOrSignature: "getProtocolVersion" ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getPubdataPricingMode" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getStateTransitionManager" + ): TypedContractMethod<[], [string], "view">; getFunction( nameOrSignature: "getTotalBatchesCommitted" ): TypedContractMethod<[], [bigint], "view">; @@ -1453,6 +1860,18 @@ export interface IZkSync extends BaseContract { [void], "nonpayable" >; + getFunction( + nameOrSignature: "proveBatchesSharedBridge" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _prevBatch: IExecutor.StoredBatchInfoStruct, + _committedBatches: IExecutor.StoredBatchInfoStruct[], + _proof: IExecutor.ProofInputStruct + ], + [void], + "nonpayable" + >; getFunction( nameOrSignature: "proveL1ToL2TransactionStatus" ): TypedContractMethod< @@ -1471,7 +1890,7 @@ export interface IZkSync extends BaseContract { nameOrSignature: "proveL2LogInclusion" ): TypedContractMethod< [ - _l2BatchNumber: BigNumberish, + _batchNumber: BigNumberish, _index: BigNumberish, _log: L2LogStruct, _proof: BytesLike[] @@ -1483,7 +1902,7 @@ export interface IZkSync extends BaseContract { nameOrSignature: "proveL2MessageInclusion" ): TypedContractMethod< [ - _l2BatchNumber: BigNumberish, + _batchNumber: BigNumberish, _index: BigNumberish, _message: L2MessageStruct, _proof: BytesLike[] @@ -1510,15 +1929,15 @@ export interface IZkSync extends BaseContract { nameOrSignature: "revertBatches" ): TypedContractMethod<[_newLastBatch: BigNumberish], [void], "nonpayable">; getFunction( - nameOrSignature: "setPendingAdmin" - ): TypedContractMethod<[_newPendingAdmin: AddressLike], [void], "nonpayable">; - getFunction( - nameOrSignature: "setPendingGovernor" + nameOrSignature: "revertBatchesSharedBridge" ): TypedContractMethod< - [_newPendingGovernor: AddressLike], + [_chainId: BigNumberish, _newLastBatch: BigNumberish], [void], "nonpayable" >; + getFunction( + nameOrSignature: "setPendingAdmin" + ): TypedContractMethod<[_newPendingAdmin: AddressLike], [void], "nonpayable">; getFunction( nameOrSignature: "setPorterAvailability" ): TypedContractMethod<[_zkPorterIsAvailable: boolean], [void], "nonpayable">; @@ -1529,6 +1948,20 @@ export interface IZkSync extends BaseContract { [void], "nonpayable" >; + getFunction( + nameOrSignature: "setTokenMultiplier" + ): TypedContractMethod< + [_nominator: BigNumberish, _denominator: BigNumberish], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "setTransactionFilterer" + ): TypedContractMethod< + [_transactionFilterer: AddressLike], + [void], + "nonpayable" + >; getFunction( nameOrSignature: "setValidator" ): TypedContractMethod< @@ -1536,12 +1969,25 @@ export interface IZkSync extends BaseContract { [void], "nonpayable" >; + getFunction( + nameOrSignature: "setValidiumMode" + ): TypedContractMethod<[_validiumMode: BigNumberish], [void], "nonpayable">; getFunction( nameOrSignature: "storedBatchHash" ): TypedContractMethod<[_batchNumber: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "transferEthToSharedBridge" + ): TypedContractMethod<[], [void], "nonpayable">; getFunction( nameOrSignature: "unfreezeDiamond" ): TypedContractMethod<[], [void], "nonpayable">; + getFunction( + nameOrSignature: "upgradeChainFromVersion" + ): TypedContractMethod< + [_protocolVersion: BigNumberish, _cutData: Diamond.DiamondCutDataStruct], + [void], + "nonpayable" + >; getEvent( key: "BlockCommit" @@ -1607,11 +2053,18 @@ export interface IZkSync extends BaseContract { NewAdminEvent.OutputObject >; getEvent( - key: "NewGovernor" + key: "NewBaseTokenMultiplier" + ): TypedContractEvent< + NewBaseTokenMultiplierEvent.InputTuple, + NewBaseTokenMultiplierEvent.OutputTuple, + NewBaseTokenMultiplierEvent.OutputObject + >; + getEvent( + key: "NewFeeParams" ): TypedContractEvent< - NewGovernorEvent.InputTuple, - NewGovernorEvent.OutputTuple, - NewGovernorEvent.OutputObject + NewFeeParamsEvent.InputTuple, + NewFeeParamsEvent.OutputTuple, + NewFeeParamsEvent.OutputObject >; getEvent( key: "NewPendingAdmin" @@ -1620,13 +2073,6 @@ export interface IZkSync extends BaseContract { NewPendingAdminEvent.OutputTuple, NewPendingAdminEvent.OutputObject >; - getEvent( - key: "NewPendingGovernor" - ): TypedContractEvent< - NewPendingGovernorEvent.InputTuple, - NewPendingGovernorEvent.OutputTuple, - NewPendingGovernorEvent.OutputObject - >; getEvent( key: "NewPriorityRequest" ): TypedContractEvent< @@ -1641,6 +2087,20 @@ export interface IZkSync extends BaseContract { NewPriorityTxMaxGasLimitEvent.OutputTuple, NewPriorityTxMaxGasLimitEvent.OutputObject >; + getEvent( + key: "NewTransactionFilterer" + ): TypedContractEvent< + NewTransactionFiltererEvent.InputTuple, + NewTransactionFiltererEvent.OutputTuple, + NewTransactionFiltererEvent.OutputObject + >; + getEvent( + key: "ProposeTransparentUpgrade" + ): TypedContractEvent< + ProposeTransparentUpgradeEvent.InputTuple, + ProposeTransparentUpgradeEvent.OutputTuple, + ProposeTransparentUpgradeEvent.OutputObject + >; getEvent( key: "Unfreeze" ): TypedContractEvent< @@ -1655,6 +2115,13 @@ export interface IZkSync extends BaseContract { ValidatorStatusUpdateEvent.OutputTuple, ValidatorStatusUpdateEvent.OutputObject >; + getEvent( + key: "ValidiumModeStatusUpdate" + ): TypedContractEvent< + ValidiumModeStatusUpdateEvent.InputTuple, + ValidiumModeStatusUpdateEvent.OutputTuple, + ValidiumModeStatusUpdateEvent.OutputObject + >; filters: { "BlockCommit(uint256,bytes32,bytes32)": TypedContractEvent< @@ -1756,15 +2223,26 @@ export interface IZkSync extends BaseContract { NewAdminEvent.OutputObject >; - "NewGovernor(address,address)": TypedContractEvent< - NewGovernorEvent.InputTuple, - NewGovernorEvent.OutputTuple, - NewGovernorEvent.OutputObject + "NewBaseTokenMultiplier(uint128,uint128,uint128,uint128)": TypedContractEvent< + NewBaseTokenMultiplierEvent.InputTuple, + NewBaseTokenMultiplierEvent.OutputTuple, + NewBaseTokenMultiplierEvent.OutputObject >; - NewGovernor: TypedContractEvent< - NewGovernorEvent.InputTuple, - NewGovernorEvent.OutputTuple, - NewGovernorEvent.OutputObject + NewBaseTokenMultiplier: TypedContractEvent< + NewBaseTokenMultiplierEvent.InputTuple, + NewBaseTokenMultiplierEvent.OutputTuple, + NewBaseTokenMultiplierEvent.OutputObject + >; + + "NewFeeParams(tuple,tuple)": TypedContractEvent< + NewFeeParamsEvent.InputTuple, + NewFeeParamsEvent.OutputTuple, + NewFeeParamsEvent.OutputObject + >; + NewFeeParams: TypedContractEvent< + NewFeeParamsEvent.InputTuple, + NewFeeParamsEvent.OutputTuple, + NewFeeParamsEvent.OutputObject >; "NewPendingAdmin(address,address)": TypedContractEvent< @@ -1778,17 +2256,6 @@ export interface IZkSync extends BaseContract { NewPendingAdminEvent.OutputObject >; - "NewPendingGovernor(address,address)": TypedContractEvent< - NewPendingGovernorEvent.InputTuple, - NewPendingGovernorEvent.OutputTuple, - NewPendingGovernorEvent.OutputObject - >; - NewPendingGovernor: TypedContractEvent< - NewPendingGovernorEvent.InputTuple, - NewPendingGovernorEvent.OutputTuple, - NewPendingGovernorEvent.OutputObject - >; - "NewPriorityRequest(uint256,bytes32,uint64,tuple,bytes[])": TypedContractEvent< NewPriorityRequestEvent.InputTuple, NewPriorityRequestEvent.OutputTuple, @@ -1811,6 +2278,28 @@ export interface IZkSync extends BaseContract { NewPriorityTxMaxGasLimitEvent.OutputObject >; + "NewTransactionFilterer(address,address)": TypedContractEvent< + NewTransactionFiltererEvent.InputTuple, + NewTransactionFiltererEvent.OutputTuple, + NewTransactionFiltererEvent.OutputObject + >; + NewTransactionFilterer: TypedContractEvent< + NewTransactionFiltererEvent.InputTuple, + NewTransactionFiltererEvent.OutputTuple, + NewTransactionFiltererEvent.OutputObject + >; + + "ProposeTransparentUpgrade(tuple,uint256,bytes32)": TypedContractEvent< + ProposeTransparentUpgradeEvent.InputTuple, + ProposeTransparentUpgradeEvent.OutputTuple, + ProposeTransparentUpgradeEvent.OutputObject + >; + ProposeTransparentUpgrade: TypedContractEvent< + ProposeTransparentUpgradeEvent.InputTuple, + ProposeTransparentUpgradeEvent.OutputTuple, + ProposeTransparentUpgradeEvent.OutputObject + >; + "Unfreeze()": TypedContractEvent< UnfreezeEvent.InputTuple, UnfreezeEvent.OutputTuple, @@ -1832,5 +2321,16 @@ export interface IZkSync extends BaseContract { ValidatorStatusUpdateEvent.OutputTuple, ValidatorStatusUpdateEvent.OutputObject >; + + "ValidiumModeStatusUpdate(uint8)": TypedContractEvent< + ValidiumModeStatusUpdateEvent.InputTuple, + ValidiumModeStatusUpdateEvent.OutputTuple, + ValidiumModeStatusUpdateEvent.OutputObject + >; + ValidiumModeStatusUpdate: TypedContractEvent< + ValidiumModeStatusUpdateEvent.InputTuple, + ValidiumModeStatusUpdateEvent.OutputTuple, + ValidiumModeStatusUpdateEvent.OutputObject + >; }; } diff --git a/src/typechain/factories/IBridgehub__factory.ts b/src/typechain/factories/IBridgehub__factory.ts new file mode 100644 index 00000000..5857bf79 --- /dev/null +++ b/src/typechain/factories/IBridgehub__factory.ts @@ -0,0 +1,648 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { IBridgehub, IBridgehubInterface } from "../IBridgehub"; + +const _abi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "oldAdmin", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newAdmin", + type: "address", + }, + ], + name: "NewAdmin", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: false, + internalType: "address", + name: "stateTransitionManager", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "chainGovernance", + type: "address", + }, + ], + name: "NewChain", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "oldPendingAdmin", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newPendingAdmin", + type: "address", + }, + ], + name: "NewPendingAdmin", + type: "event", + }, + { + inputs: [], + name: "acceptAdmin", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_stateTransitionManager", + type: "address", + }, + ], + name: "addStateTransitionManager", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_token", + type: "address", + }, + ], + name: "addToken", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + ], + name: "baseToken", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_stateTransitionManager", + type: "address", + }, + { + internalType: "address", + name: "_baseToken", + type: "address", + }, + { + internalType: "uint256", + name: "_salt", + type: "uint256", + }, + { + internalType: "address", + name: "_admin", + type: "address", + }, + { + internalType: "bytes", + name: "_initData", + type: "bytes", + }, + ], + name: "createNewChain", + outputs: [ + { + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + ], + name: "getStateTransition", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_gasPrice", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2GasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2GasPerPubdataByteLimit", + type: "uint256", + }, + ], + name: "l2TransactionBaseCost", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + { + internalType: "enum TxStatus", + name: "_status", + type: "uint8", + }, + ], + name: "proveL1ToL2TransactionStatus", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_batchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_index", + type: "uint256", + }, + { + components: [ + { + internalType: "uint8", + name: "l2ShardId", + type: "uint8", + }, + { + internalType: "bool", + name: "isService", + type: "bool", + }, + { + internalType: "uint16", + name: "txNumberInBatch", + type: "uint16", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + { + internalType: "bytes32", + name: "key", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "value", + type: "bytes32", + }, + ], + internalType: "struct L2Log", + name: "_log", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "_proof", + type: "bytes32[]", + }, + ], + name: "proveL2LogInclusion", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_batchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_index", + type: "uint256", + }, + { + components: [ + { + internalType: "uint16", + name: "txNumberInBatch", + type: "uint16", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + { + internalType: "bytes", + name: "data", + type: "bytes", + }, + ], + internalType: "struct L2Message", + name: "_message", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "_proof", + type: "bytes32[]", + }, + ], + name: "proveL2MessageInclusion", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_stateTransitionManager", + type: "address", + }, + ], + name: "removeStateTransitionManager", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "mintValue", + type: "uint256", + }, + { + internalType: "address", + name: "l2Contract", + type: "address", + }, + { + internalType: "uint256", + name: "l2Value", + type: "uint256", + }, + { + internalType: "bytes", + name: "l2Calldata", + type: "bytes", + }, + { + internalType: "uint256", + name: "l2GasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2GasPerPubdataByteLimit", + type: "uint256", + }, + { + internalType: "bytes[]", + name: "factoryDeps", + type: "bytes[]", + }, + { + internalType: "address", + name: "refundRecipient", + type: "address", + }, + ], + internalType: "struct L2TransactionRequestDirect", + name: "_request", + type: "tuple", + }, + ], + name: "requestL2TransactionDirect", + outputs: [ + { + internalType: "bytes32", + name: "canonicalTxHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "mintValue", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2Value", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2GasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2GasPerPubdataByteLimit", + type: "uint256", + }, + { + internalType: "address", + name: "refundRecipient", + type: "address", + }, + { + internalType: "address", + name: "secondBridgeAddress", + type: "address", + }, + { + internalType: "uint256", + name: "secondBridgeValue", + type: "uint256", + }, + { + internalType: "bytes", + name: "secondBridgeCalldata", + type: "bytes", + }, + ], + internalType: "struct L2TransactionRequestTwoBridgesOuter", + name: "_request", + type: "tuple", + }, + ], + name: "requestL2TransactionTwoBridges", + outputs: [ + { + internalType: "bytes32", + name: "canonicalTxHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_newPendingAdmin", + type: "address", + }, + ], + name: "setPendingAdmin", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_sharedBridge", + type: "address", + }, + ], + name: "setSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "sharedBridge", + outputs: [ + { + internalType: "contract IL1SharedBridge", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + ], + name: "stateTransitionManager", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_stateTransitionManager", + type: "address", + }, + ], + name: "stateTransitionManagerIsRegistered", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_baseToken", + type: "address", + }, + ], + name: "tokenIsRegistered", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, +] as const; + +export class IBridgehub__factory { + static readonly abi = _abi; + static createInterface(): IBridgehubInterface { + return new Interface(_abi) as IBridgehubInterface; + } + static connect(address: string, runner?: ContractRunner | null): IBridgehub { + return new Contract(address, _abi, runner) as unknown as IBridgehub; + } +} diff --git a/src/typechain/factories/IContractDeployer__factory.ts b/src/typechain/factories/IContractDeployer__factory.ts index 52ce9945..111bb9cf 100644 --- a/src/typechain/factories/IContractDeployer__factory.ts +++ b/src/typechain/factories/IContractDeployer__factory.ts @@ -94,7 +94,7 @@ const _abi = [ outputs: [ { internalType: "address", - name: "newAddress", + name: "", type: "address", }, ], @@ -123,7 +123,7 @@ const _abi = [ outputs: [ { internalType: "address", - name: "newAddress", + name: "", type: "address", }, ], @@ -157,7 +157,7 @@ const _abi = [ outputs: [ { internalType: "address", - name: "newAddress", + name: "", type: "address", }, ], @@ -168,7 +168,7 @@ const _abi = [ inputs: [ { internalType: "bytes32", - name: "_salt", + name: "", type: "bytes32", }, { @@ -191,10 +191,114 @@ const _abi = [ outputs: [ { internalType: "address", - name: "newAddress", + name: "", + type: "address", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_address", + type: "address", + }, + ], + name: "extendedAccountVersion", + outputs: [ + { + internalType: "enum IContractDeployer.AccountAbstractionVersion", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "bytecodeHash", + type: "bytes32", + }, + { + internalType: "address", + name: "newAddress", + type: "address", + }, + { + internalType: "bool", + name: "callConstructor", + type: "bool", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + { + internalType: "bytes", + name: "input", + type: "bytes", + }, + ], + internalType: "struct ContractDeployer.ForceDeployment", + name: "_deployment", + type: "tuple", + }, + { + internalType: "address", + name: "_sender", type: "address", }, ], + name: "forceDeployOnAddress", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "bytecodeHash", + type: "bytes32", + }, + { + internalType: "address", + name: "newAddress", + type: "address", + }, + { + internalType: "bool", + name: "callConstructor", + type: "bool", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + { + internalType: "bytes", + name: "input", + type: "bytes", + }, + ], + internalType: "struct ContractDeployer.ForceDeployment[]", + name: "_deployments", + type: "tuple[]", + }, + ], + name: "forceDeployOnAddresses", + outputs: [], stateMutability: "payable", type: "function", }, diff --git a/src/typechain/factories/IL1Bridge__factory.ts b/src/typechain/factories/IL1Bridge__factory.ts index 64491451..d8eddb96 100644 --- a/src/typechain/factories/IL1Bridge__factory.ts +++ b/src/typechain/factories/IL1Bridge__factory.ts @@ -9,6 +9,80 @@ const _abi = [ { anonymous: false, inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "bytes32", + name: "l2DepositTxHash", + type: "bytes32", + }, + ], + name: "BridgehubDepositFinalized", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "BridgehubDepositInitiatedSharedBridge", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, { indexed: true, internalType: "address", @@ -28,12 +102,18 @@ const _abi = [ type: "uint256", }, ], - name: "ClaimedFailedDeposit", + name: "ClaimedFailedDepositSharedBridge", type: "event", }, { anonymous: false, inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, { indexed: true, internalType: "bytes32", @@ -47,7 +127,7 @@ const _abi = [ type: "address", }, { - indexed: true, + indexed: false, internalType: "address", name: "to", type: "address", @@ -65,12 +145,18 @@ const _abi = [ type: "uint256", }, ], - name: "DepositInitiated", + name: "DepositInitiatedSharedBridge", type: "event", }, { anonymous: false, inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, { indexed: true, internalType: "address", @@ -90,11 +176,136 @@ const _abi = [ type: "uint256", }, ], - name: "WithdrawalFinalized", + name: "WithdrawalFinalizedSharedBridge", type: "event", }, + { + inputs: [], + name: "bridgehub", + outputs: [ + { + internalType: "contract IBridgehub", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_txDataHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "_txHash", + type: "bytes32", + }, + ], + name: "bridgehubConfirmL2Transaction", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_prevMsgSender", + type: "address", + }, + { + internalType: "bytes", + name: "_data", + type: "bytes", + }, + ], + name: "bridgehubDeposit", + outputs: [ + { + components: [ + { + internalType: "bytes32", + name: "magicValue", + type: "bytes32", + }, + { + internalType: "address", + name: "l2Contract", + type: "address", + }, + { + internalType: "bytes", + name: "l2Calldata", + type: "bytes", + }, + { + internalType: "bytes[]", + name: "factoryDeps", + type: "bytes[]", + }, + { + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + ], + internalType: "struct L2TransactionRequestTwoBridgesInner", + name: "request", + type: "tuple", + }, + ], + stateMutability: "payable", + type: "function", + }, { inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_prevMsgSender", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + ], + name: "bridgehubDepositBaseToken", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, { internalType: "address", name: "_depositSender", @@ -105,6 +316,11 @@ const _abi = [ name: "_l1Token", type: "address", }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, { internalType: "bytes32", name: "_l2TxHash", @@ -138,6 +354,11 @@ const _abi = [ }, { inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, { internalType: "address", name: "_l2Receiver", @@ -148,6 +369,11 @@ const _abi = [ name: "_l1Token", type: "address", }, + { + internalType: "uint256", + name: "_mintValue", + type: "uint256", + }, { internalType: "uint256", name: "_amount", @@ -182,6 +408,35 @@ const _abi = [ }, { inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + ], + name: "depositHappened", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, { internalType: "uint256", name: "_l2BatchNumber", @@ -215,6 +470,11 @@ const _abi = [ }, { inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, { internalType: "uint256", name: "_l2BatchNumber", @@ -226,7 +486,7 @@ const _abi = [ type: "uint256", }, ], - name: "isWithdrawalFinalized", + name: "isWithdrawalFinalizedShared", outputs: [ { internalType: "bool", @@ -237,28 +497,15 @@ const _abi = [ stateMutability: "view", type: "function", }, - { - inputs: [], - name: "l2Bridge", - outputs: [ - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, { inputs: [ { - internalType: "address", - name: "_l1Token", - type: "address", + internalType: "uint256", + name: "_chainId", + type: "uint256", }, ], - name: "l2TokenAddress", + name: "l2BridgeAddress", outputs: [ { internalType: "address", diff --git a/src/typechain/factories/IL1ERC20Bridge__factory.ts b/src/typechain/factories/IL1ERC20Bridge__factory.ts new file mode 100644 index 00000000..2a6557cd --- /dev/null +++ b/src/typechain/factories/IL1ERC20Bridge__factory.ts @@ -0,0 +1,400 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { + IL1ERC20Bridge, + IL1ERC20BridgeInterface, +} from "../IL1ERC20Bridge"; + +const _abi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "ClaimedFailedDeposit", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "l2DepositTxHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "DepositInitiated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "WithdrawalFinalized", + type: "event", + }, + { + inputs: [ + { + internalType: "address", + name: "_depositSender", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "claimFailedDeposit", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_l2Receiver", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasPerPubdataByte", + type: "uint256", + }, + ], + name: "deposit", + outputs: [ + { + internalType: "bytes32", + name: "txHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_l2Receiver", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasPerPubdataByte", + type: "uint256", + }, + { + internalType: "address", + name: "_refundRecipient", + type: "address", + }, + ], + name: "deposit", + outputs: [ + { + internalType: "bytes32", + name: "txHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_account", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "bytes32", + name: "_depositL2TxHash", + type: "bytes32", + }, + ], + name: "depositAmount", + outputs: [ + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes", + name: "_message", + type: "bytes", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "finalizeWithdrawal", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + ], + name: "isWithdrawalFinalized", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "l2Bridge", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + ], + name: "l2TokenAddress", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "l2TokenBeacon", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "sharedBridge", + outputs: [ + { + internalType: "contract IL1SharedBridge", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + ], + name: "transferTokenToSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const; + +export class IL1ERC20Bridge__factory { + static readonly abi = _abi; + static createInterface(): IL1ERC20BridgeInterface { + return new Interface(_abi) as IL1ERC20BridgeInterface; + } + static connect( + address: string, + runner?: ContractRunner | null + ): IL1ERC20Bridge { + return new Contract(address, _abi, runner) as unknown as IL1ERC20Bridge; + } +} diff --git a/src/typechain/factories/IL1SharedBridge__factory.ts b/src/typechain/factories/IL1SharedBridge__factory.ts new file mode 100644 index 00000000..d34709f9 --- /dev/null +++ b/src/typechain/factories/IL1SharedBridge__factory.ts @@ -0,0 +1,715 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { + IL1SharedBridge, + IL1SharedBridgeInterface, +} from "../IL1SharedBridge"; + +const _abi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "BridgehubDepositBaseTokenInitiated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "bytes32", + name: "l2DepositTxHash", + type: "bytes32", + }, + ], + name: "BridgehubDepositFinalized", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "BridgehubDepositInitiated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "ClaimedFailedDepositSharedBridge", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "l2DepositTxHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "LegacyDepositInitiated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "WithdrawalFinalizedSharedBridge", + type: "event", + }, + { + inputs: [], + name: "bridgehub", + outputs: [ + { + internalType: "contract IBridgehub", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_txDataHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "_txHash", + type: "bytes32", + }, + ], + name: "bridgehubConfirmL2Transaction", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_prevMsgSender", + type: "address", + }, + { + internalType: "uint256", + name: "_l2Value", + type: "uint256", + }, + { + internalType: "bytes", + name: "_data", + type: "bytes", + }, + ], + name: "bridgehubDeposit", + outputs: [ + { + components: [ + { + internalType: "bytes32", + name: "magicValue", + type: "bytes32", + }, + { + internalType: "address", + name: "l2Contract", + type: "address", + }, + { + internalType: "bytes", + name: "l2Calldata", + type: "bytes", + }, + { + internalType: "bytes[]", + name: "factoryDeps", + type: "bytes[]", + }, + { + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + ], + internalType: "struct L2TransactionRequestTwoBridgesInner", + name: "request", + type: "tuple", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_prevMsgSender", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + ], + name: "bridgehubDepositBaseToken", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_depositSender", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "claimFailedDeposit", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_depositSender", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "claimFailedDepositLegacyErc20Bridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + ], + name: "depositHappened", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_msgSender", + type: "address", + }, + { + internalType: "address", + name: "_l2Receiver", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasPerPubdataByte", + type: "uint256", + }, + { + internalType: "address", + name: "_refundRecipient", + type: "address", + }, + ], + name: "depositLegacyErc20Bridge", + outputs: [ + { + internalType: "bytes32", + name: "txHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes", + name: "_message", + type: "bytes", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "finalizeWithdrawal", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes", + name: "_message", + type: "bytes", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "finalizeWithdrawalLegacyErc20Bridge", + outputs: [ + { + internalType: "address", + name: "l1Receiver", + type: "address", + }, + { + internalType: "address", + name: "l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + ], + name: "isWithdrawalFinalized", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "l1WethAddress", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + ], + name: "l2BridgeAddress", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "legacyBridge", + outputs: [ + { + internalType: "contract IL1ERC20Bridge", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + ], + name: "receiveEth", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_eraFirstPostUpgradeBatch", + type: "uint256", + }, + ], + name: "setEraFirstPostUpgradeBatch", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const; + +export class IL1SharedBridge__factory { + static readonly abi = _abi; + static createInterface(): IL1SharedBridgeInterface { + return new Interface(_abi) as IL1SharedBridgeInterface; + } + static connect( + address: string, + runner?: ContractRunner | null + ): IL1SharedBridge { + return new Contract(address, _abi, runner) as unknown as IL1SharedBridge; + } +} diff --git a/src/typechain/factories/ITestnetERC20Token__factory.ts b/src/typechain/factories/ITestnetERC20Token__factory.ts new file mode 100644 index 00000000..15d1a2ea --- /dev/null +++ b/src/typechain/factories/ITestnetERC20Token__factory.ts @@ -0,0 +1,62 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { + ITestnetERC20Token, + ITestnetERC20TokenInterface, +} from "../ITestnetERC20Token"; + +const _abi = [ + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_to", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + ], + name: "mint", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, +] as const; + +export class ITestnetERC20Token__factory { + static readonly abi = _abi; + static createInterface(): ITestnetERC20TokenInterface { + return new Interface(_abi) as ITestnetERC20TokenInterface; + } + static connect( + address: string, + runner?: ContractRunner | null + ): ITestnetERC20Token { + return new Contract(address, _abi, runner) as unknown as ITestnetERC20Token; + } +} diff --git a/src/typechain/factories/IZkSync__factory.ts b/src/typechain/factories/IZkSyncStateTransition__factory.ts similarity index 63% rename from src/typechain/factories/IZkSync__factory.ts rename to src/typechain/factories/IZkSyncStateTransition__factory.ts index 84c32e58..e8478c54 100644 --- a/src/typechain/factories/IZkSync__factory.ts +++ b/src/typechain/factories/IZkSyncStateTransition__factory.ts @@ -3,7 +3,10 @@ /* eslint-disable */ import { Contract, Interface, type ContractRunner } from "ethers"; -import type { IZkSync, IZkSyncInterface } from "../IZkSync"; +import type { + IZkSyncStateTransition, + IZkSyncStateTransitionInterface, +} from "../IZkSyncStateTransition"; const _abi = [ { @@ -213,38 +216,114 @@ const _abi = [ anonymous: false, inputs: [ { - indexed: true, - internalType: "address", - name: "oldGovernor", - type: "address", + indexed: false, + internalType: "uint128", + name: "oldNominator", + type: "uint128", }, { - indexed: true, - internalType: "address", - name: "newGovernor", - type: "address", + indexed: false, + internalType: "uint128", + name: "oldDenominator", + type: "uint128", + }, + { + indexed: false, + internalType: "uint128", + name: "newNominator", + type: "uint128", + }, + { + indexed: false, + internalType: "uint128", + name: "newDenominator", + type: "uint128", }, ], - name: "NewGovernor", + name: "NewBaseTokenMultiplier", type: "event", }, { anonymous: false, inputs: [ { - indexed: true, - internalType: "address", - name: "oldPendingAdmin", - type: "address", + components: [ + { + internalType: "enum PubdataPricingMode", + name: "pubdataPricingMode", + type: "uint8", + }, + { + internalType: "uint32", + name: "batchOverheadL1Gas", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxPubdataPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxL2GasPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "priorityTxMaxPubdata", + type: "uint32", + }, + { + internalType: "uint64", + name: "minimalL2GasPrice", + type: "uint64", + }, + ], + indexed: false, + internalType: "struct FeeParams", + name: "oldFeeParams", + type: "tuple", }, { - indexed: true, - internalType: "address", - name: "newPendingAdmin", - type: "address", + components: [ + { + internalType: "enum PubdataPricingMode", + name: "pubdataPricingMode", + type: "uint8", + }, + { + internalType: "uint32", + name: "batchOverheadL1Gas", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxPubdataPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxL2GasPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "priorityTxMaxPubdata", + type: "uint32", + }, + { + internalType: "uint64", + name: "minimalL2GasPrice", + type: "uint64", + }, + ], + indexed: false, + internalType: "struct FeeParams", + name: "newFeeParams", + type: "tuple", }, ], - name: "NewPendingAdmin", + name: "NewFeeParams", type: "event", }, { @@ -253,17 +332,17 @@ const _abi = [ { indexed: true, internalType: "address", - name: "oldPendingGovernor", + name: "oldPendingAdmin", type: "address", }, { indexed: true, internalType: "address", - name: "newPendingGovernor", + name: "newPendingAdmin", type: "address", }, ], - name: "NewPendingGovernor", + name: "NewPendingAdmin", type: "event", }, { @@ -371,7 +450,7 @@ const _abi = [ }, ], indexed: false, - internalType: "struct IMailbox.L2CanonicalTransaction", + internalType: "struct L2CanonicalTransaction", name: "transaction", type: "tuple", }, @@ -404,6 +483,89 @@ const _abi = [ name: "NewPriorityTxMaxGasLimit", type: "event", }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "oldTransactionFilterer", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "newTransactionFilterer", + type: "address", + }, + ], + name: "NewTransactionFilterer", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + components: [ + { + internalType: "address", + name: "facet", + type: "address", + }, + { + internalType: "enum Diamond.Action", + name: "action", + type: "uint8", + }, + { + internalType: "bool", + name: "isFreezable", + type: "bool", + }, + { + internalType: "bytes4[]", + name: "selectors", + type: "bytes4[]", + }, + ], + internalType: "struct Diamond.FacetCut[]", + name: "facetCuts", + type: "tuple[]", + }, + { + internalType: "address", + name: "initAddress", + type: "address", + }, + { + internalType: "bytes", + name: "initCalldata", + type: "bytes", + }, + ], + indexed: false, + internalType: "struct Diamond.DiamondCutData", + name: "diamondCut", + type: "tuple", + }, + { + indexed: true, + internalType: "uint256", + name: "proposalId", + type: "uint256", + }, + { + indexed: false, + internalType: "bytes32", + name: "proposalSalt", + type: "bytes32", + }, + ], + name: "ProposeTransparentUpgrade", + type: "event", + }, { anonymous: false, inputs: [], @@ -429,6 +591,19 @@ const _abi = [ name: "ValidatorStatusUpdate", type: "event", }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "enum PubdataPricingMode", + name: "validiumMode", + type: "uint8", + }, + ], + name: "ValidiumModeStatusUpdate", + type: "event", + }, { inputs: [], name: "acceptAdmin", @@ -438,7 +613,137 @@ const _abi = [ }, { inputs: [], - name: "acceptGovernor", + name: "baseTokenGasPriceMultiplierDenominator", + outputs: [ + { + internalType: "uint128", + name: "", + type: "uint128", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "baseTokenGasPriceMultiplierNominator", + outputs: [ + { + internalType: "uint128", + name: "", + type: "uint128", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "sender", + type: "address", + }, + { + internalType: "address", + name: "contractL2", + type: "address", + }, + { + internalType: "uint256", + name: "mintValue", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2Value", + type: "uint256", + }, + { + internalType: "bytes", + name: "l2Calldata", + type: "bytes", + }, + { + internalType: "uint256", + name: "l2GasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2GasPerPubdataByteLimit", + type: "uint256", + }, + { + internalType: "bytes[]", + name: "factoryDeps", + type: "bytes[]", + }, + { + internalType: "address", + name: "refundRecipient", + type: "address", + }, + ], + internalType: "struct BridgehubL2TransactionRequest", + name: "_request", + type: "tuple", + }, + ], + name: "bridgehubRequestL2Transaction", + outputs: [ + { + internalType: "bytes32", + name: "canonicalTxHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "enum PubdataPricingMode", + name: "pubdataPricingMode", + type: "uint8", + }, + { + internalType: "uint32", + name: "batchOverheadL1Gas", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxPubdataPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxL2GasPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "priorityTxMaxPubdata", + type: "uint32", + }, + { + internalType: "uint64", + name: "minimalL2GasPrice", + type: "uint64", + }, + ], + internalType: "struct FeeParams", + name: "_newFeeParams", + type: "tuple", + }, + ], + name: "changeFeeParams", outputs: [], stateMutability: "nonpayable", type: "function", @@ -541,7 +846,7 @@ const _abi = [ }, { internalType: "bytes", - name: "totalL2ToL1Pubdata", + name: "pubdataCommitments", type: "bytes", }, ], @@ -555,6 +860,123 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo", + name: "_lastCommittedBatchData", + type: "tuple", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "uint64", + name: "timestamp", + type: "uint64", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "bytes32", + name: "newStateRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "bootloaderHeapInitialContentsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "eventsQueueStateHash", + type: "bytes32", + }, + { + internalType: "bytes", + name: "systemLogs", + type: "bytes", + }, + { + internalType: "bytes", + name: "pubdataCommitments", + type: "bytes", + }, + ], + internalType: "struct IExecutor.CommitBatchInfo[]", + name: "_newBatchesData", + type: "tuple[]", + }, + ], + name: "commitBatchesSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [ { @@ -610,6 +1032,66 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo[]", + name: "_batchesData", + type: "tuple[]", + }, + ], + name: "executeBatchesSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [ { @@ -780,12 +1262,12 @@ const _abi = [ }, { inputs: [], - name: "getFirstUnprocessedPriorityTx", + name: "getAdmin", outputs: [ { - internalType: "uint256", + internalType: "address", name: "", - type: "uint256", + type: "address", }, ], stateMutability: "view", @@ -793,12 +1275,51 @@ const _abi = [ }, { inputs: [], - name: "getGovernor", + name: "getBaseToken", outputs: [ { internalType: "address", name: "", - type: "address", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getBaseTokenBridge", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getBridgehub", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getFirstUnprocessedPriorityTx", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", }, ], stateMutability: "view", @@ -871,7 +1392,7 @@ const _abi = [ }, { inputs: [], - name: "getPendingGovernor", + name: "getPendingAdmin", outputs: [ { internalType: "address", @@ -921,6 +1442,32 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "getPubdataPricingMode", + outputs: [ + { + internalType: "enum PubdataPricingMode", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getStateTransitionManager", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, { inputs: [], name: "getTotalBatchesCommitted", @@ -1122,7 +1669,7 @@ const _abi = [ outputs: [ { internalType: "bytes32", - name: "hash", + name: "merkleRoot", type: "bytes32", }, ], @@ -1307,6 +1854,130 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo", + name: "_prevBatch", + type: "tuple", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo[]", + name: "_committedBatches", + type: "tuple[]", + }, + { + components: [ + { + internalType: "uint256[]", + name: "recursiveAggregationInput", + type: "uint256[]", + }, + { + internalType: "uint256[]", + name: "serializedProof", + type: "uint256[]", + }, + ], + internalType: "struct IExecutor.ProofInput", + name: "_proof", + type: "tuple", + }, + ], + name: "proveBatchesSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [ { @@ -1355,7 +2026,7 @@ const _abi = [ inputs: [ { internalType: "uint256", - name: "_l2BatchNumber", + name: "_batchNumber", type: "uint256", }, { @@ -1421,7 +2092,7 @@ const _abi = [ inputs: [ { internalType: "uint256", - name: "_l2BatchNumber", + name: "_batchNumber", type: "uint256", }, { @@ -1533,12 +2204,17 @@ const _abi = [ { inputs: [ { - internalType: "address", - name: "_newPendingAdmin", - type: "address", + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_newLastBatch", + type: "uint256", }, ], - name: "setPendingAdmin", + name: "revertBatchesSharedBridge", outputs: [], stateMutability: "nonpayable", type: "function", @@ -1547,11 +2223,11 @@ const _abi = [ inputs: [ { internalType: "address", - name: "_newPendingGovernor", + name: "_newPendingAdmin", type: "address", }, ], - name: "setPendingGovernor", + name: "setPendingAdmin", outputs: [], stateMutability: "nonpayable", type: "function", @@ -1582,6 +2258,37 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "uint128", + name: "_nominator", + type: "uint128", + }, + { + internalType: "uint128", + name: "_denominator", + type: "uint128", + }, + ], + name: "setTokenMultiplier", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_transactionFilterer", + type: "address", + }, + ], + name: "setTransactionFilterer", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [ { @@ -1600,6 +2307,19 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "enum PubdataPricingMode", + name: "_validiumMode", + type: "uint8", + }, + ], + name: "setValidiumMode", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [ { @@ -1619,6 +2339,13 @@ const _abi = [ stateMutability: "view", type: "function", }, + { + inputs: [], + name: "transferEthToSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, { inputs: [], name: "unfreezeDiamond", @@ -1626,14 +2353,78 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [ + { + internalType: "uint256", + name: "_protocolVersion", + type: "uint256", + }, + { + components: [ + { + components: [ + { + internalType: "address", + name: "facet", + type: "address", + }, + { + internalType: "enum Diamond.Action", + name: "action", + type: "uint8", + }, + { + internalType: "bool", + name: "isFreezable", + type: "bool", + }, + { + internalType: "bytes4[]", + name: "selectors", + type: "bytes4[]", + }, + ], + internalType: "struct Diamond.FacetCut[]", + name: "facetCuts", + type: "tuple[]", + }, + { + internalType: "address", + name: "initAddress", + type: "address", + }, + { + internalType: "bytes", + name: "initCalldata", + type: "bytes", + }, + ], + internalType: "struct Diamond.DiamondCutData", + name: "_cutData", + type: "tuple", + }, + ], + name: "upgradeChainFromVersion", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, ] as const; -export class IZkSync__factory { +export class IZkSyncStateTransition__factory { static readonly abi = _abi; - static createInterface(): IZkSyncInterface { - return new Interface(_abi) as IZkSyncInterface; + static createInterface(): IZkSyncStateTransitionInterface { + return new Interface(_abi) as IZkSyncStateTransitionInterface; } - static connect(address: string, runner?: ContractRunner | null): IZkSync { - return new Contract(address, _abi, runner) as unknown as IZkSync; + static connect( + address: string, + runner?: ContractRunner | null + ): IZkSyncStateTransition { + return new Contract( + address, + _abi, + runner + ) as unknown as IZkSyncStateTransition; } } diff --git a/src/typechain/factories/index.ts b/src/typechain/factories/index.ts index 84f0ad81..c34566e2 100644 --- a/src/typechain/factories/index.ts +++ b/src/typechain/factories/index.ts @@ -1,13 +1,17 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +export { IBridgehub__factory } from "./IBridgehub__factory"; export { IContractDeployer__factory } from "./IContractDeployer__factory"; export { IERC1271__factory } from "./IERC1271__factory"; export { IERC20__factory } from "./IERC20__factory"; export { IEthToken__factory } from "./IEthToken__factory"; export { IL1Bridge__factory } from "./IL1Bridge__factory"; +export { IL1ERC20Bridge__factory } from "./IL1ERC20Bridge__factory"; export { IL1Messenger__factory } from "./IL1Messenger__factory"; +export { IL1SharedBridge__factory } from "./IL1SharedBridge__factory"; export { IL2Bridge__factory } from "./IL2Bridge__factory"; export { INonceHolder__factory } from "./INonceHolder__factory"; export { IPaymasterFlow__factory } from "./IPaymasterFlow__factory"; -export { IZkSync__factory } from "./IZkSync__factory"; +export { ITestnetERC20Token__factory } from "./ITestnetERC20Token__factory"; +export { IZkSyncStateTransition__factory } from "./IZkSyncStateTransition__factory"; diff --git a/src/typechain/index.ts b/src/typechain/index.ts index 61222d25..1a973270 100644 --- a/src/typechain/index.ts +++ b/src/typechain/index.ts @@ -1,24 +1,32 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +export type { IBridgehub } from "./IBridgehub"; export type { IContractDeployer } from "./IContractDeployer"; export type { IERC1271 } from "./IERC1271"; export type { IERC20 } from "./IERC20"; export type { IEthToken } from "./IEthToken"; export type { IL1Bridge } from "./IL1Bridge"; +export type { IL1ERC20Bridge } from "./IL1ERC20Bridge"; export type { IL1Messenger } from "./IL1Messenger"; +export type { IL1SharedBridge } from "./IL1SharedBridge"; export type { IL2Bridge } from "./IL2Bridge"; export type { INonceHolder } from "./INonceHolder"; export type { IPaymasterFlow } from "./IPaymasterFlow"; -export type { IZkSync } from "./IZkSync"; +export type { ITestnetERC20Token } from "./ITestnetERC20Token"; +export type { IZkSyncStateTransition } from "./IZkSyncStateTransition"; export * as factories from "./factories"; +export { IBridgehub__factory } from "./factories/IBridgehub__factory"; export { IContractDeployer__factory } from "./factories/IContractDeployer__factory"; export { IERC1271__factory } from "./factories/IERC1271__factory"; export { IERC20__factory } from "./factories/IERC20__factory"; export { IEthToken__factory } from "./factories/IEthToken__factory"; export { IL1Bridge__factory } from "./factories/IL1Bridge__factory"; +export { IL1ERC20Bridge__factory } from "./factories/IL1ERC20Bridge__factory"; export { IL1Messenger__factory } from "./factories/IL1Messenger__factory"; +export { IL1SharedBridge__factory } from "./factories/IL1SharedBridge__factory"; export { IL2Bridge__factory } from "./factories/IL2Bridge__factory"; export { INonceHolder__factory } from "./factories/INonceHolder__factory"; export { IPaymasterFlow__factory } from "./factories/IPaymasterFlow__factory"; -export { IZkSync__factory } from "./factories/IZkSync__factory"; +export { ITestnetERC20Token__factory } from "./factories/ITestnetERC20Token__factory"; +export { IZkSyncStateTransition__factory } from "./factories/IZkSyncStateTransition__factory"; diff --git a/src/utils.ts b/src/utils.ts index c5d5a0dd..673c72ff 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -13,13 +13,14 @@ import { } from './types'; import {Provider} from './provider'; import {EIP712Signer} from './signer'; -import {IERC20__factory, IL1Bridge__factory} from './typechain'; -import IZkSyncABI from '../abi/IZkSync.json'; +import {IERC20__factory} from './typechain'; +import IZkSyncABI from '../abi/IZkSyncStateTransition.json'; +import IBridgehubABI from '../abi/IBridgehub.json'; import IContractDeployerABI from '../abi/IContractDeployer.json'; import IL1MessengerABI from '../abi/IL1Messenger.json'; import IERC20ABI from '../abi/IERC20.json'; import IERC1271ABI from '../abi/IERC1271.json'; -import IL1BridgeABI from '../abi/IL1Bridge.json'; +import IL1BridgeABI from '../abi/IL1ERC20Bridge.json'; import IL2BridgeABI from '../abi/IL2Bridge.json'; import INonceHolderABI from '../abi/INonceHolder.json'; @@ -33,6 +34,12 @@ export {EIP712_TYPES} from './signer'; */ export const ZKSYNC_MAIN_ABI = new ethers.Interface(IZkSyncABI); +/** + * The ABI of the `Bridgehub` interface. + * @constant + */ +export const BRIDGEHUB_ABI = new ethers.Interface(IBridgehubABI); + /** * The ABI for the `IContractDeployer` interface, which is utilized for deploying smart contracts. * @constant @@ -82,6 +89,17 @@ export const NONCE_HOLDER_ABI = new ethers.Interface(INonceHolderABI); export const ETH_ADDRESS: Address = '0x0000000000000000000000000000000000000000'; +/** + * The address of the L1 `ETH` token. + * @constant + */ +export const LEGACY_ETH_ADDRESS: Address = + '0x0000000000000000000000000000000000000000'; + +// in the contracts the zero address can not be used, use one instead +export const ETH_ADDRESS_IN_CONTRACTS: Address = + '0x0000000000000000000000000000000000000001'; + /** * The formal address for the `Bootloader`. * @constant @@ -106,10 +124,18 @@ export const L1_MESSENGER_ADDRESS: Address = /** * The address of the L2 `ETH` token. * @constant + * @deprecated In favor of {@link L2_BASE_TOKEN_ADDRESS}. */ export const L2_ETH_TOKEN_ADDRESS: Address = '0x000000000000000000000000000000000000800a'; +/** + * The address of the base token. + * @constant + */ +export const L2_BASE_TOKEN_ADDRESS = + '0x000000000000000000000000000000000000800a'; + /** * The address of the Nonce holder. * @constant @@ -215,12 +241,13 @@ export const REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT = 800; * @example * * const isL1ETH = utils.isETH(utils.ETH_ADDRESS); // true - * const isL2ETH = utils.isETH(utils.L2_ETH_TOKEN_ADDRESS); // true + * const isL2ETH = utils.isETH(utils.ETH_ADDRESS_IN_CONTRACTS); // true */ -export function isETH(token: Address): boolean { +export function isETH(token: Address) { return ( - token.toLowerCase() === ETH_ADDRESS || - token.toLowerCase() === L2_ETH_TOKEN_ADDRESS + token.toLowerCase() === LEGACY_ETH_ADDRESS || + token.toLowerCase() === L2_BASE_TOKEN_ADDRESS || + token.toLowerCase() === ETH_ADDRESS_IN_CONTRACTS ); } @@ -840,9 +867,12 @@ export async function getERC20DefaultBridgeData( ): Promise { const token = IERC20__factory.connect(l1TokenAddress, provider); - const name = await token.name(); - const symbol = await token.symbol(); - const decimals = await token.decimals(); + const name = + l1TokenAddress === ETH_ADDRESS_IN_CONTRACTS ? 'Ether' : await token.name(); + const symbol = + l1TokenAddress === ETH_ADDRESS_IN_CONTRACTS ? 'ETH' : await token.symbol(); + const decimals = + l1TokenAddress === ETH_ADDRESS_IN_CONTRACTS ? 18 : await token.decimals(); const coder = new AbiCoder(); @@ -1106,8 +1136,7 @@ export async function estimateDefaultBridgeDepositL2Gas( // due to storage slot aggregation, the gas estimation will depend on the address // and so estimation for the zero address may be smaller than for the sender. from ??= ethers.Wallet.createRandom().address; - - if (token === ETH_ADDRESS) { + if (await providerL2.isBaseToken(token)) { return await providerL2.estimateL1ToL2Execute({ contractAddress: to, gasPerPubdataByte: gasPerPubdataByte, @@ -1116,35 +1145,17 @@ export async function estimateDefaultBridgeDepositL2Gas( l2Value: amount, }); } else { - let value, l1BridgeAddress, l2BridgeAddress, bridgeData; const bridgeAddresses = await providerL2.getDefaultBridgeAddresses(); - const l1WethBridge = IL1Bridge__factory.connect( - bridgeAddresses.wethL1!, - providerL1 - ); - let l2WethToken = ethers.ZeroAddress; - try { - l2WethToken = await l1WethBridge.l2TokenAddress(token); - } catch (e) { - // skip - } - if (l2WethToken !== ethers.ZeroAddress) { - value = amount; - l1BridgeAddress = bridgeAddresses.wethL1; - l2BridgeAddress = bridgeAddresses.wethL2; - bridgeData = '0x'; - } else { - value = 0; - l1BridgeAddress = bridgeAddresses.erc20L1; - l2BridgeAddress = bridgeAddresses.erc20L2; - bridgeData = await getERC20DefaultBridgeData(token, providerL1); - } + const value = 0; + const l1BridgeAddress = bridgeAddresses.sharedL1; + const l2BridgeAddress = bridgeAddresses.sharedL2; + const bridgeData = await getERC20DefaultBridgeData(token, providerL1); return await estimateCustomBridgeDepositL2Gas( providerL2, - l1BridgeAddress!, - l2BridgeAddress!, + l1BridgeAddress, + l2BridgeAddress, token, amount, to, @@ -1233,7 +1244,7 @@ export async function estimateCustomBridgeDepositL2Gas( export function toJSON(object: any): string { return JSON.stringify( object, - (key, value) => { + (_, value) => { if (typeof value === 'bigint') { return value.toString(); // Convert BigInt to string } diff --git a/src/wallet.ts b/src/wallet.ts index e2d92e58..7f422012 100644 --- a/src/wallet.ts +++ b/src/wallet.ts @@ -22,7 +22,13 @@ import { TransactionResponse, } from './types'; import {AdapterL1, AdapterL2} from './adapters'; -import {IL1Bridge, IL2Bridge, IZkSync} from './typechain'; +import { + IBridgehub, + IL1ERC20Bridge, + IL1SharedBridge, + IL2Bridge, + IZkSyncStateTransition, +} from './typechain'; /** * A `Wallet` is an extension of {@link ethers.Wallet} with additional features for interacting with zkSync Era. @@ -36,7 +42,9 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { override _providerL1(): ethers.Provider { if (!this.providerL1) { - throw new Error('L1 provider missing: use `connectToL1` to specify!'); + throw new Error( + 'L1 provider is missing! Specify an L1 provider using `Wallet.connectToL1()`.' + ); } return this.providerL1; } @@ -67,12 +75,32 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { * const ethProvider = ethers.getDefaultProvider("sepolia"); * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); * - * console.log(`Main contract: ${await wallet.getMainContract()}`); + * const mainContract = await wallet.getMainContract(); */ - override async getMainContract(): Promise { + override async getMainContract(): Promise { return super.getMainContract(); } + /** + * @inheritDoc + * + * @example + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const bridgehub = await wallet.getBridgehubContract(); + */ + override async getBridgehubContract(): Promise { + return super.getBridgehubContract(); + } + /** * @inheritDoc * @@ -90,8 +118,8 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { * const l1BridgeContracts = await wallet.getL1BridgeContracts(); */ override async getL1BridgeContracts(): Promise<{ - erc20: IL1Bridge; - weth: IL1Bridge; + erc20: IL1ERC20Bridge; + shared: IL1SharedBridge; }> { return super.getL1BridgeContracts(); } @@ -235,25 +263,229 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { * const ethProvider = ethers.getDefaultProvider("sepolia"); * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); * + * console.log(`Base token: ${await wallet.getBaseToken()}`); + */ + override async getBaseToken(): Promise { + return super.getBaseToken(); + } + + /** + * @inheritDoc + * + * @example + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * console.log(`Is ETH-based chain: ${await wallet.isETHBasedChain()}`); + */ + override async isETHBasedChain(): Promise { + return super.isETHBasedChain(); + } + + /** + * @inheritDoc + * + * @example Get allowance parameters for depositing ETH on non-ETH-based chain. + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const token = utils.LEGACY_ETH_ADDRESS; + * const amount = 5; + * const approveParams = await wallet.getDepositAllowanceParams(token, amount); + * + * await ( + * await wallet.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * @example Get allowance parameters for depositing base token on non-ETH-based chain. + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const token = await wallet.getBaseToken(); + * const amount = 5; + * const approveParams = await wallet.getDepositAllowanceParams(token, amount); + * + * await ( + * await wallet.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * @example Get allowance parameters for depositing non-base token on non-ETH-based chain. + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const token = ""; + * const amount = 5; + * const approveParams = await wallet.getDepositAllowanceParams(token, amount); + * + * await ( + * await wallet.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * await ( + * await wallet.approveERC20( + * approveParams[1].token, + * approveParams[1].allowance + * ) + * ).wait(); + */ + override async getDepositAllowanceParams( + token: Address, + amount: BigNumberish + ): Promise< + { + token: Address; + allowance: BigNumberish; + }[] + > { + return super.getDepositAllowanceParams(token, amount); + } + + /** + * @inheritDoc + * + * @example Deposit ETH on ETH-based chain. + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const tx = await wallet.deposit({ + * token: utils.ETH_ADDRESS, + * amount: 10_000_000, + * }); + * // Note that we wait not only for the L1 transaction to complete but also for it to be + * // processed by zkSync. If we want to wait only for the transaction to be processed on L1, + * // we can use `await tx.waitL1Commit()` + * await tx.wait(); + * + * @example Deposit token on ETH-based chain. + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * * const tokenL1 = "0x56E69Fa1BB0d1402c89E3A4E3417882DeA6B14Be"; - * const tokenDepositHandle = await wallet.deposit({ + * const tx = await wallet.deposit({ * token: tokenL1, - * amount: "10000000", + * amount: 10_000_000, * approveERC20: true, * }); * // Note that we wait not only for the L1 transaction to complete but also for it to be * // processed by zkSync. If we want to wait only for the transaction to be processed on L1, - * // we can use `await tokenDepositHandle.waitL1Commit()` - * await tokenDepositHandle.wait(); + * // we can use `await tx.waitL1Commit()` + * await tx.wait(); + * + * @example Deposit ETH on non-ETH-based chain. + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; * - * const ethDepositHandle = await wallet.deposit({ + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const tx = await wallet.deposit({ * token: utils.ETH_ADDRESS, - * amount: "10000000", + * amount: 10_000_000, + * approveBaseERC20: true, + * }); + * // Note that we wait not only for the L1 transaction to complete but also for it to be + * // processed by zkSync. If we want to wait only for the transaction to be processed on L1, + * // we can use `await tx.waitL1Commit()` + * await tx.wait(); + * + * @example Deposit base token on non-ETH-based chain. + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const tx = await wallet.deposit({ + * token: await wallet.getBaseToken(), + * amount: 10_000_000, + * approveERC20: true, // or approveBaseERC20: true + * }); + * // Note that we wait not only for the L1 transaction to complete but also for it to be + * // processed by zkSync. If we want to wait only for the transaction to be processed on L1, + * // we can use `await tx.waitL1Commit()` + * await tx.wait(); + * + * @example Deposit non-base token on non-ETH-based chain. + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const tokenL1 = "0x56E69Fa1BB0d1402c89E3A4E3417882DeA6B14Be"; + * const tx = await wallet.deposit({ + * token: tokenL1, + * amount: 10_000_000, + * approveERC20: true, + * approveBaseERC20: true, * }); * // Note that we wait not only for the L1 transaction to complete but also for it to be * // processed by zkSync. If we want to wait only for the transaction to be processed on L1, - * // we can use `await ethDepositHandle.waitL1Commit()` - * await ethDepositHandle.wait(); + * // we can use `await tx.waitL1Commit()` + * await tx.wait(); */ override async deposit(transaction: { token: Address; @@ -262,11 +494,13 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { operatorTip?: BigNumberish; bridgeAddress?: Address; approveERC20?: boolean; + approveBaseERC20?: boolean; l2GasLimit?: BigNumberish; gasPerPubdataByte?: BigNumberish; refundRecipient?: Address; - overrides?: Overrides; - approveOverrides?: Overrides; + overrides?: ethers.Overrides; + approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; customBridgeData?: BytesLike; }): Promise { return super.deposit(transaction); @@ -338,7 +572,7 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { gasPerPubdataByte?: BigNumberish; customBridgeData?: BytesLike; refundRecipient?: Address; - overrides?: Overrides; + overrides?: ethers.Overrides; }): Promise { return super.getDepositTx(transaction); } @@ -472,6 +706,48 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { return super.claimFailedDeposit(depositHash, overrides); } + /** + * @inheritDoc + * + * @example + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const tx = { + * contractAddress: await wallet.getAddress(), + * calldata: '0x', + * l2Value: 7_000_000_000, + * }; + * + * const approveParams = await wallet.getRequestExecuteAllowanceParams(tx); + * await ( + * await wallet.approveERC20( + * approveParams.token, + * approveParams.allowance + * ) + * ).wait(); + */ + override async getRequestExecuteAllowanceParams(transaction: { + contractAddress: Address; + calldata: string; + l2GasLimit?: BigNumberish; + l2Value?: BigNumberish; + factoryDeps?: BytesLike[]; + operatorTip?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: Overrides; + }): Promise<{token: Address; allowance: BigNumberish}> { + return super.getRequestExecuteAllowanceParams(transaction); + } + /** * @inheritDoc * @@ -569,12 +845,13 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { contractAddress: Address; calldata: string; l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; - factoryDeps?: BytesLike[]; + factoryDeps?: ethers.BytesLike[]; operatorTip?: BigNumberish; gasPerPubdataByte?: BigNumberish; refundRecipient?: Address; - overrides?: Overrides; + overrides?: ethers.Overrides; }): Promise { return super.getRequestExecuteTx(transaction); } @@ -674,8 +951,7 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { * const l2BridgeContracts = await wallet.getL2BridgeContracts(); */ override async getL2BridgeContracts(): Promise<{ - erc20: IL2Bridge; - weth: IL2Bridge; + shared: IL2Bridge; }> { return super.getL2BridgeContracts(); } @@ -788,6 +1064,36 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { return super.transfer(transaction); } + /** + * @inheritDoc + * + * @example + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const wallet = new Wallet(PRIVATE_KEY, provider); + * + * // Any L2 -> L1 transaction can be used. + * // In this case, withdrawal transaction is used. + * const tx = "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e"; + * console.log(`Confirmation data: ${utils.toJSON(await wallet.getPriorityOpConfirmation(tx, 0))}`); + */ + override async getPriorityOpConfirmation( + txHash: string, + index = 0 + ): Promise<{ + l1BatchNumber: number; + l2MessageIndex: number; + l2TxNumberInBlock: number | null; + proof: string[]; + }> { + return super.getPriorityOpConfirmation(txHash, index); + } + /** * Returns `ethers.Wallet` object with the same private key. * diff --git a/tests/custom-matchers.ts b/tests/custom-matchers.ts index c3c5fb15..5748bc0b 100644 --- a/tests/custom-matchers.ts +++ b/tests/custom-matchers.ts @@ -1,4 +1,7 @@ import * as chai from 'chai'; +import {types} from '../src'; + +const {expect} = chai; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace @@ -24,3 +27,47 @@ chai.Assertion.addMethod( } } ); + +// Custom assertion function for BigNumber values with a percentage tolerance +export function expectBigNumberCloseTo( + actual: bigint, + expected: bigint, + tolerancePercentage: number +) { + const actualPercentageDiff = ((actual - expected) * 100n) / expected; + const abs = + actualPercentageDiff < 0n ? -actualPercentageDiff : actualPercentageDiff; + expect(abs < tolerancePercentage).to.be.true; +} + +export function expectFeeDataCloseToExpected( + result: types.FullDepositFee, + expected: types.FullDepositFee, + tolerancePercentage: number +) { + expectBigNumberCloseTo( + result.baseCost.valueOf(), + expected.baseCost.valueOf(), + tolerancePercentage + ); + expectBigNumberCloseTo( + result.l1GasLimit.valueOf(), + expected.l1GasLimit.valueOf(), + tolerancePercentage + ); + expectBigNumberCloseTo( + result.l2GasLimit.valueOf(), + expected.l2GasLimit.valueOf(), + tolerancePercentage + ); + expectBigNumberCloseTo( + result.maxFeePerGas!.valueOf(), + expected.maxFeePerGas!.valueOf(), + tolerancePercentage + ); + expectBigNumberCloseTo( + result.maxPriorityFeePerGas!.valueOf(), + expected.maxPriorityFeePerGas!.valueOf(), + tolerancePercentage + ); +} diff --git a/tests/files/tokens.json b/tests/files/tokens.json index 1b9fdb79..da31cd61 100644 --- a/tests/files/tokens.json +++ b/tests/files/tokens.json @@ -1,98 +1,98 @@ [ - { - "name": "DAI", - "symbol": "DAI", - "decimals": 18, - "address": "0x70a0F165d6f8054d0d0CF8dFd4DD2005f0AF6B55" - }, - { - "name": "wBTC", - "symbol": "wBTC", - "decimals": 8, - "address": "0x1C552d7B40b38Fb1235697Bed7b8e1e47B46e5BA" - }, - { - "name": "BAT", - "symbol": "BAT", - "decimals": 18, - "address": "0xdF2Ff03eAAfae59fA7fd30D4f91ab045B3d5D95D" - }, - { - "name": "GNT", - "symbol": "GNT", - "decimals": 18, - "address": "0xeF81A0BB8819F94EEf15992F31555a282d7009d1" - }, - { - "name": "MLTT", - "symbol": "MLTT", - "decimals": 18, - "address": "0x9ad574a765F65Ec554780c2b5D97979Ed1957d30" - }, - { - "name": "DAIK", - "symbol": "DAIK", - "decimals": 18, - "address": "0x266B465D9D37cF6001d38b8e3f839fAE0e10D619" - }, - { - "name": "wBTCK", - "symbol": "wBTCK", - "decimals": 8, - "address": "0x05789138d7838a4707FFB45EA5B2c498B1e8Be3c" - }, - { - "name": "BATK", - "symbol": "BATS", - "decimals": 18, - "address": "0xfeC8FE20C644fab5d37B86E821A29F1abfEdFc55" - }, - { - "name": "GNTK", - "symbol": "GNTS", - "decimals": 18, - "address": "0xde617bf595d8090c63350CA3916b13FBD79f0E0a" - }, - { - "name": "MLTTK", - "symbol": "MLTTS", - "decimals": 18, - "address": "0x0B827231D3ECE7906361723170701941f5813191" - }, - { - "name": "DAIL", - "symbol": "DAIL", - "decimals": 18, - "address": "0x4EDe5c04d0eF5aDDD222cc7D3C4cbE23Ac7fD4F4" - }, - { - "name": "wBTCL", - "symbol": "wBTCP", - "decimals": 8, - "address": "0x2E694B999D7746Dcf3864E9C2F47a4daEBD65721" - }, - { - "name": "BATL", - "symbol": "BATW", - "decimals": 18, - "address": "0x0a1D1D084645a46E9E019da345684308701855b6" - }, - { - "name": "GNTL", - "symbol": "GNTW", - "decimals": 18, - "address": "0x1630bcE01eb41A9Fd5d49a14e5c6D52b1B127d17" - }, - { - "name": "MLTTL", - "symbol": "MLTTW", - "decimals": 18, - "address": "0xa60bc9ae6a6967CAC6D8b08e12a2EF087348Cd32" - }, - { - "name": "Wrapped Ether", - "symbol": "WETH", - "decimals": 18, - "address": "0x4A470422bFf67C34a3A565106118023059fa4E34" - } + { + "name": "DAI", + "symbol": "DAI", + "decimals": 18, + "address": "0x70a0F165d6f8054d0d0CF8dFd4DD2005f0AF6B55" + }, + { + "name": "wBTC", + "symbol": "wBTC", + "decimals": 8, + "address": "0xAfb5167116e6B833889018916594aC8040DbC05F" + }, + { + "name": "BAT", + "symbol": "BAT", + "decimals": 18, + "address": "0x8E9C82509488eD471A83824d20Dd474b8F534a0b" + }, + { + "name": "GNT", + "symbol": "GNT", + "decimals": 18, + "address": "0x54FCb2405EE4f574C4F09333d25c401E68aD3408" + }, + { + "name": "MLTT", + "symbol": "MLTT", + "decimals": 18, + "address": "0xBac0B12C39a7Bd98172aC283E71fD951D998E4ac" + }, + { + "name": "DAIK", + "symbol": "DAIK", + "decimals": 18, + "address": "0x414C663bFf0358623a1392C6B4C416DeD6fED244" + }, + { + "name": "wBTCK", + "symbol": "wBTCK", + "decimals": 8, + "address": "0xa45cfbb064d940615F3db0D61e3C316d5264B2be" + }, + { + "name": "BATK", + "symbol": "BATS", + "decimals": 18, + "address": "0x565439D05A8F7Fd26AA60A46b3026e9D74172292" + }, + { + "name": "GNTK", + "symbol": "GNTS", + "decimals": 18, + "address": "0xc118ac58c87F65318a70532f4F033B1786CCFF78" + }, + { + "name": "MLTTK", + "symbol": "MLTTS", + "decimals": 18, + "address": "0x3fad2B2E21eA1c96618Cc76a42Fb5a77c3f71c6F" + }, + { + "name": "DAIL", + "symbol": "DAIL", + "decimals": 18, + "address": "0x2B0f9ED4F5D95C6C0f0B093f9F210603EdbF4232" + }, + { + "name": "wBTCL", + "symbol": "wBTCP", + "decimals": 8, + "address": "0xa2Ed35BcE8c6cF76f2d830a48D234586DcCf2204" + }, + { + "name": "BATL", + "symbol": "BATW", + "decimals": 18, + "address": "0x1C552d7B40b38Fb1235697Bed7b8e1e47B46e5BA" + }, + { + "name": "GNTL", + "symbol": "GNTW", + "decimals": 18, + "address": "0x1f13B4147Fd8251Fd7b637f50423cB7BFee83B09" + }, + { + "name": "MLTTL", + "symbol": "MLTTW", + "decimals": 18, + "address": "0x09786e9dbC9DaAa02e490f8b010b9B027C6Fb44A" + }, + { + "name": "Wrapped Ether", + "symbol": "WETH", + "decimals": 18, + "address": "0x3c0E6C514fC91CcD894CadaBd0cB848332053c9c" + } ] diff --git a/tests/integration/account-abstraction.test.ts b/tests/integration/account-abstraction.test.ts index dd6b7c63..7df63989 100644 --- a/tests/integration/account-abstraction.test.ts +++ b/tests/integration/account-abstraction.test.ts @@ -3,6 +3,7 @@ import '../custom-matchers'; import {Provider, types, utils, Wallet, ContractFactory} from '../../src'; import {Contract, ethers, Typed} from 'ethers'; import {ECDSASmartAccount, MultisigECDSASmartAccount} from '../../src'; +import {ADDRESS1, PRIVATE_KEY1, APPROVAL_TOKEN, PAYMASTER} from '../utils'; const {expect} = chai; @@ -12,15 +13,8 @@ import Storage from '../files/Storage.json'; import MultisigAccount from '../files/TwoUserMultisig.json'; describe('Account Abstraction', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); - const wallet = new Wallet(PRIVATE_KEY, provider); - - const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; - const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; + const wallet = new Wallet(PRIVATE_KEY1, provider); it('use the ERC20 token for paying transaction fee', async () => { const InitMintAmount = 10n; @@ -112,7 +106,7 @@ describe('Account Abstraction', () => { it('use multisig account', async () => { const storageValue = 500n; - const account = ECDSASmartAccount.create(ADDRESS, PRIVATE_KEY, provider); + const account = ECDSASmartAccount.create(ADDRESS1, PRIVATE_KEY1, provider); const multisigAccountAbi = MultisigAccount.abi; const multisigAccountBytecode: string = MultisigAccount.bytecode; @@ -140,11 +134,11 @@ describe('Account Abstraction', () => { // send paymaster approval token to multisig account const sendApprovalTokenTx = await new Wallet( - PRIVATE_KEY, + PRIVATE_KEY1, provider ).transfer({ to: multisigAddress, - token: TOKEN, + token: APPROVAL_TOKEN, amount: 5, }); await sendApprovalTokenTx.wait(); @@ -182,7 +176,7 @@ describe('Account Abstraction', () => { const minimalAllowance = 1n; const storageValue = 700n; - const account = ECDSASmartAccount.create(ADDRESS, PRIVATE_KEY, provider); + const account = ECDSASmartAccount.create(ADDRESS1, PRIVATE_KEY1, provider); const storageAbi = Storage.contracts['Storage.sol:Storage'].abi; const storageBytecode: string = @@ -195,13 +189,14 @@ describe('Account Abstraction', () => { const storage = (await storageFactory.deploy()) as Contract; const accountBalanceBeforeTx = await account.getBalance(); - const accountApprovalTokenBalanceBeforeTx = await account.getBalance(TOKEN); + const accountApprovalTokenBalanceBeforeTx = + await account.getBalance(APPROVAL_TOKEN); const paymasterSetTx = await storage.set(storageValue, { customData: { paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -210,7 +205,8 @@ describe('Account Abstraction', () => { await paymasterSetTx.wait(); const accountBalanceAfterTx = await account.getBalance(); - const accountApprovalTokenBalanceAfterTx = await account.getBalance(TOKEN); + const accountApprovalTokenBalanceAfterTx = + await account.getBalance(APPROVAL_TOKEN); expect(accountBalanceBeforeTx === accountBalanceAfterTx).to.be.true; expect( diff --git a/tests/integration/contract.test.ts b/tests/integration/contract.test.ts index d9724a47..160f20e0 100644 --- a/tests/integration/contract.test.ts +++ b/tests/integration/contract.test.ts @@ -2,23 +2,18 @@ import * as chai from 'chai'; import '../custom-matchers'; import {ContractFactory, Provider, types, Wallet, Contract} from '../../src'; import {ethers} from 'ethers'; +import {PRIVATE_KEY1, DAI_L1} from '../utils'; const {expect} = chai; -import TokensL1 from '../files/tokens.json'; import Token from '../files/Token.json'; import Paymaster from '../files/Paymaster.json'; import Storage from '../files/Storage.json'; import Demo from '../files/Demo.json'; describe('ContractFactory', () => { - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); - const wallet = new Wallet(PRIVATE_KEY, provider); - - const DAI_L1 = TokensL1[0].address; + const wallet = new Wallet(PRIVATE_KEY1, provider); describe('#constructor()', () => { it('`ContractFactory(abi, bytecode, runner)` should return a `ContractFactory` with `create` deployment', async () => { diff --git a/tests/integration/provider.test.ts b/tests/integration/provider.test.ts index b5834950..9cbd3010 100644 --- a/tests/integration/provider.test.ts +++ b/tests/integration/provider.test.ts @@ -2,30 +2,30 @@ import {expect} from 'chai'; import '../custom-matchers'; import {Provider, types, utils, Wallet} from '../../src'; import {ethers} from 'ethers'; - -import TokensL1 from '../files/tokens.json'; +import { + IS_ETH_BASED, + ADDRESS1, + PRIVATE_KEY1, + ADDRESS2, + DAI_L1, + APPROVAL_TOKEN, + PAYMASTER, +} from '../utils'; describe('Provider', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); - const wallet = new Wallet(PRIVATE_KEY, provider); - - const DAI_L1 = TokensL1[0].address; - - const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; - const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; + const wallet = new Wallet(PRIVATE_KEY1, provider); let receipt: types.TransactionReceipt; + let baseToken: string; before('setup', async function () { this.timeout(25_000); + + baseToken = await provider.getBaseTokenContractAddress(); const tx = await wallet.transfer({ - token: utils.ETH_ADDRESS, - to: RECEIVER, + token: utils.LEGACY_ETH_ADDRESS, + to: ADDRESS2, amount: 1_000_000, }); receipt = await tx.wait(); @@ -72,11 +72,17 @@ describe('Provider', () => { }); }); + describe('#getBridgehubContractAddress()', () => { + it('should return the address of main contract', async () => { + const result = await provider.getBridgehubContractAddress(); + expect(result).not.to.be.null; + }); + }); + describe('#getTestnetPaymasterAddress()', () => { it('should return the address of testnet paymaster', async () => { - const TESTNET_PAYMASTER = '0x59067204f2789ffcb6eadb6be6c7cbb7be9fdc7c'; const result = await provider.getTestnetPaymasterAddress(); - expect(result).to.be.equal(TESTNET_PAYMASTER); + expect(result).not.to.be.null; }); }); @@ -97,9 +103,8 @@ describe('Provider', () => { describe('#getGasPrice()', () => { it('should return a gas price', async () => { - const GAS_PRICE = 250_000_000n; const result = await provider.getGasPrice(); - expect(result).to.be.equal(GAS_PRICE); + expect(result).to.be.equal(100_000_000n); }); }); @@ -112,13 +117,13 @@ describe('Provider', () => { describe('#getBalance()', () => { it('should return an ETH balance of the account at `address`', async () => { - const result = await provider.getBalance(ADDRESS); + const result = await provider.getBalance(ADDRESS1); expect(result > 0).to.be.true; }); it('should return a DAI balance of the account at `address`', async () => { const result = await provider.getBalance( - ADDRESS, + ADDRESS1, 'latest', await provider.l2TokenAddress(DAI_L1) ); @@ -128,8 +133,9 @@ describe('Provider', () => { describe('#getAllAccountBalances()', () => { it('should return the all balances of the account at `address`', async () => { - const result = await provider.getAllAccountBalances(ADDRESS); - expect(Object.keys(result)).to.have.lengthOf(2); // ETH, DAI + const result = await provider.getAllAccountBalances(ADDRESS1); + const expected = IS_ETH_BASED ? 2 : 3; + expect(Object.keys(result)).to.have.lengthOf(expected); }); }); @@ -149,11 +155,12 @@ describe('Provider', () => { describe('#getBytecodeByHash()', () => { it('should return the bytecode of a contract', async () => { - const testnetPaymasterBytecode = - '0x000200000000000200090000000000020001000000010355000000800b0000390000004000b0043f00000000030100190000006003300270000000b2033001970000000102200190000000430000c13d000000040230008c0000004b0000413d000000000201043b000000e002200270000000b40420009c0000004f0000613d000000b50220009c000000630000c13d000000040230008a000000c00420008c000000630000413d0000000404100370000000000404043b000000b60540009c000000630000213d0000002305400039000000b706000041000000000735004b00000000070000190000000007068019000000b705500197000000000805004b0000000006008019000000b70550009c000000000607c019000000000506004b000000630000c13d0000000405400039000000000551034f000000000505043b000000b60650009c000000630000213d00000000045400190000002404400039000000000334004b000000630000213d0000002403100370000000000303043b000000b60430009c000000630000213d0000000002320049000000b703000041000002600420008c00000000040000190000000004034019000000b702200197000000000502004b000000000300a019000000b70220009c000000000304c019000000000203004b000000630000c13d0000008401100370000000000101043b000000010110008c000000630000213d0000004d0000013d0000000001000416000000000101004b000000630000c13d000000200100003900000100001004430000012000000443000000b301000041000002c50001042e000000000103004b000000630000c13d0000000001000019000002c50001042e000000040230008a000000600220008c000000630000413d0000004402100370000000000202043b000000b60420009c000000630000213d00000004042000390000000005430049000000b706000041000002600750008c00000000070000190000000007064019000000b708500197000000000908004b000000000600a019000000b70880009c000000000607c019000000000606004b000000650000613d0000000001000019000002c6000104300000000006000411000080010660008c000000990000c13d0000022406200039000000000661034f000000000606043b0000001f0550008a000000b707000041000000000856004b00000000080000190000000008078019000000b705500197000000b709600197000000000a59004b0000000007008019000000000559013f000000b70550009c000000000708c019000000000507004b000000630000c13d0000000004460019000000000541034f000000000505043b000000b60650009c000000630000213d00000000065300490000002003400039000000b707000041000000000863004b00000000080000190000000008072019000000b706600197000000b709300197000000000a69004b0000000007008019000000000669013f000000b70660009c000000000708c019000000000607004b000000630000c13d000000030650008c000000a50000213d000000b801000041000000800010043f0000002001000039000000840010043f0000003a01000039000000a40010043f000000d201000041000000c40010043f000000d301000041000000a20000013d000000b801000041000000800010043f0000002001000039000000840010043f0000002601000039000000a40010043f000000b901000041000000c40010043f000000ba01000041000000e40010043f000000bb01000041000002c600010430000000000631034f000000000606043b000000bc06600197000000bd0660009c000000dd0000c13d000000040550008a000000600650008c000000630000413d0000000403300039000000000631034f000000000606043b000900000006001d000000c00660009c000000630000213d0000004006300039000000000661034f0000002003300039000000000331034f000000000303043b000800000003001d000000000306043b000000b60630009c000000630000213d0000002406400039000000000465001900000000056300190000001f03500039000000b706000041000000000743004b00000000070000190000000007068019000000b703300197000000b708400197000000000983004b0000000006008019000000000383013f000000b70330009c000000000607c019000000000306004b000000630000c13d00070000000b001d000000000351034f000000000303043b000000c10630009c000000d70000813d000000bf063000390006002000000092000000060660017f000000b60760009c000000e70000a13d000000c40100004100000000001004350000004101000039000000040010043f000000c501000041000002c600010430000000b801000041000000800010043f0000002001000039000000840010043f0000001a01000039000000a40010043f000000be01000041000000c40010043f000000bf01000041000002c600010430000000400060043f000000800030043f00000020055000390000000006530019000000000446004b000000630000213d000000000451034f0000001f0530018f0000000506300272000000fa0000613d00000000070000190000000508700210000000000984034f000000000909043b000000a00880003900000000009804350000000107700039000000000867004b000000f20000413d000000000705004b000001090000613d0000000506600210000000000464034f0000000305500210000000a006600039000000000706043300000000075701cf000000000757022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000474019f0000000000460435000000a0033000390000000000030435000300240020003d0000000301100360000000000101043b000000400400043d000000c20200004100000000002404350000000002000410000000c0032001970000002402400039000100000003001d0000000000320435000000c002100197000500000004001d0000000401400039000200000002001d000000000021043500000000010004140000000902000029000000040220008c000001240000c13d0000000003000031000000200130008c00000000040300190000002004008039000001550000013d000000b202000041000000b20310009c00000000010280190000000504000029000000b20340009c00000000020440190000004002200210000000c001100210000000000121019f000000c3011001c7000000090200002902c402bf0000040f000000050a00002900000000030100190000006003300270000000b203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000001430000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b0000013b0000413d000000000705004b000001520000613d0000000506600210000000000761034f00000005066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000000000003001f00000001022001900000017d0000613d0000001f01400039000000600110018f0000000504100029000000000214004b00000000020000190000000102004039000400000004001d000000b60440009c000000d70000213d0000000102200190000000d70000c13d0000000402000029000000400020043f000000200230008c000000630000413d00000005020000290000000002020433000000080220006c000001a00000813d00000004030000290000006401300039000000d00200004100000000002104350000004401300039000000d1020000410000000000210435000000240130003900000029020000390000000000210435000000b8010000410000000000130435000000040130003900000020020000390000000000210435000000b201000041000000b20230009c00000000030180190000004001300210000000cc011001c7000002c600010430000000400200043d0000001f0430018f00000005053002720000018a0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000001820000413d000000000604004b000001990000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000000b201000041000000b20420009c000000000201801900000040012002100000006002300210000000000121019f000002c60001043000000003060000290000004002600039000000010520036700000080026000390000000102200367000000000202043b000000000405043b00050000502400ad000000000504004b000001ad0000613d00000005544000f9000000000224004b0000020b0000c13d0000000404000029000000240240003900000001050000290000000000520435000000c6020000410000000000240435000000040240003900000002050000290000000000520435000000440240003900000008040000290000000000420435000000c705000041000000050240006c0000000005004019000800000005001d00000000020004140000000904000029000000040440008c000001f40000613d000000b201000041000000b20320009c00000000020180190000000404000029000000b20340009c00000000010440190000004001100210000000c002200210000000000112019f000000c8011001c7000000090200002902c402ba0000040f000000040a00002900000000030100190000006003300270000000b203300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000001e00000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000001d80000413d000000000705004b000001ef0000613d0000000506600210000000000761034f00000004066000290000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f0000000000560435000000000003001f00000001022001900000020f0000613d0000001f01400039000000600110018f0000000401100029000000b60210009c000000d70000213d000000400010043f000000200130008c000000630000413d00000004010000290000000001010433000000000201004b0000000002000019000000010200c039000000000121004b000000630000c13d000000b2010000410000000002000414000000b20320009c0000000002018019000000c001200210000000050200006b000002500000c13d000080010200003902c402ba0000040f000002560000013d000000c40100004100000000001004350000001101000039000000da0000013d0000006002000039000000000403004b0000021f0000c13d0000000001020433000000050210008c000002490000413d000000b202000041000000b20310009c00000000010280190000000704000029000000b20340009c000000000402801900000040024002100000006001100210000000000121019f000002c6000104300000003f02300039000000c904200197000000400200043d0000000004420019000000000524004b00000000050000190000000105004039000000b60640009c000000d70000213d0000000105500190000000d70000c13d000000400040043f0000001f0430018f00000000083204360000000503300272000002380000613d000000000500001900000005065002100000000007680019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b000002300000413d000700000008001d000000000504004b000002120000613d0000000503300210000000000131034f00000007033000290000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000130435000002120000013d000000400100043d0000006402100039000000ca0300004100000000003204350000004402100039000000cb03000041000002ab0000013d000000cd011001c7000080090200003900008001040000390000000503000029000000000500001902c402ba0000040f00000000030100190000006003300270000000b20030019d000000b205300198000002830000613d0000003f03500039000000c903300197000000400400043d0000000003340019000000000643004b00000000060000190000000106004039000000b60730009c000000d70000213d0000000106600190000000d70000c13d000000400030043f0000001f0350018f00000000045404360000000505500272000002740000613d000000000600001900000005076002100000000008740019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b0000026c0000413d000000000603004b000002830000613d0000000505500210000000000151034f00000000045400190000000303300210000000000504043300000000053501cf000000000535022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000151019f0000000000140435000000400100043d0000000102200190000002a60000613d000000200210003900000040030000390000000000320435000000080200002900000000002104350000004003100039000000600200043d00000000002304350000006003100039000000000402004b000002990000613d000000000400001900000000053400190000008006400039000000000606043300000000006504350000002004400039000000000524004b000002920000413d000000000332001900000000000304350000007f02200039000000060220017f000000b203000041000000b20420009c0000000002038019000000b20410009c000000000103801900000040011002100000006002200210000000000112019f000002c50001042e0000006402100039000000ce0300004100000000003204350000004402100039000000cf03000041000000000032043500000024021000390000002a030000390000000000320435000000b8020000410000000000210435000000040210003900000020030000390000000000320435000000b202000041000000b20310009c00000000010280190000004001100210000000cc011001c7000002c600010430000002bd002104210000000102000039000000000001042d0000000002000019000000000001042d000002c2002104230000000102000039000000000001042d0000000002000019000000000001042d000002c400000432000002c50001042e000002c600010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffff000000020000000000000000000000000000004000000100000000000000000000000000000000000000000000000000000000000000000000000000038a24bc00000000000000000000000000000000000000000000000000000000817b17f0000000000000000000000000000000000000000000000000ffffffffffffffff800000000000000000000000000000000000000000000000000000000000000008c379a0000000000000000000000000000000000000000000000000000000004f6e6c7920626f6f746c6f616465722063616e2063616c6c207468697320636f6e747261637400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000800000000000000000ffffffff00000000000000000000000000000000000000000000000000000000949431dc00000000000000000000000000000000000000000000000000000000556e737570706f72746564207061796d617374657220666c6f770000000000000000000000000000000000000000000000000064000000800000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000010000000000000000dd62ed3e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000023b872dd00000000000000000000000000000000000000000000000000000000038a24bc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffe07327206163636f756e74000000000000000000000000000000000000000000004661696c656420746f207472616e7366657246726f6d2066726f6d207573657200000000000000000000000000000000000000840000000000000000000000000200000000000000000000000000000000000000000000000000000000000000626f6f746c6f61646572000000000000000000000000000000000000000000004661696c656420746f207472616e736665722066756e647320746f2074686520616c6c6f77616e63650000000000000000000000000000000000000000000000546865207573657220646964206e6f742070726f7669646520656e6f75676820546865207374616e64617264207061796d617374657220696e707574206d757374206265206174206c656173742034206279746573206c6f6e670000000000003e3fedd1037ff662aaf95f9c82a9391df33ea5e806aeb952e06b321484d378cb'; + const testnetPaymasterBytecode = await provider.getCode( + (await provider.getTestnetPaymasterAddress()) as string + ); const testnetPaymasterBytecodeHash = ethers.hexlify( utils.hashBytecode(testnetPaymasterBytecode) - ); // "0x010000d590477725d953dc54a472de0943121b913d97843dc3e49e4f8519f34d" + ); const result = await provider.getBytecodeByHash( testnetPaymasterBytecodeHash ); @@ -257,7 +264,7 @@ describe('Provider', () => { const result = await provider.newFilter({ fromBlock: 0, toBlock: 5, - address: utils.L2_ETH_TOKEN_ADDRESS, + address: utils.L2_BASE_TOKEN_ADDRESS, }); expect(result).not.to.be.null; }); @@ -272,9 +279,16 @@ describe('Provider', () => { }); describe('#l2TokenAddress()', () => { + it('should return the L2 base address', async () => { + const result = await provider.l2TokenAddress(baseToken); + expect(result).to.be.equal(utils.L2_BASE_TOKEN_ADDRESS); + }); + it('should return the L2 ETH address', async () => { - const result = await provider.l2TokenAddress(utils.ETH_ADDRESS); - expect(result).to.be.equal(utils.ETH_ADDRESS); + if (!IS_ETH_BASED) { + const result = await provider.l2TokenAddress(utils.LEGACY_ETH_ADDRESS); + expect(result).not.to.be.null; + } }); it('should return the L2 DAI address', async () => { @@ -284,9 +298,9 @@ describe('Provider', () => { }); describe('#l1TokenAddress()', () => { - it('should return the L1 ETH address', async () => { - const result = await provider.l1TokenAddress(utils.ETH_ADDRESS); - expect(result).to.be.equal(utils.ETH_ADDRESS); + it('should return L1 token address', async () => { + const result = await provider.l1TokenAddress(utils.LEGACY_ETH_ADDRESS); + expect(result).to.be.equal(utils.LEGACY_ETH_ADDRESS); }); it('should return the L1 DAI address', async () => { @@ -362,7 +376,7 @@ describe('Provider', () => { const result = await provider.getLogs({ fromBlock: 0, toBlock: 5, - address: utils.L2_ETH_TOKEN_ADDRESS, + address: utils.L2_BASE_TOKEN_ADDRESS, }); expect(result).not.to.be.null; }); @@ -371,25 +385,25 @@ describe('Provider', () => { describe('#getWithdrawTx()', () => { it('should return an ETH withdraw transaction', async () => { const tx = { - from: ADDRESS, + from: ADDRESS1, value: 7_000_000_000n, - to: '0x000000000000000000000000000000000000800a', + to: utils.L2_BASE_TOKEN_ADDRESS, data: '0x51cff8d900000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049', }; const result = await provider.getWithdrawTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, }); expect(result).to.be.deep.equal(tx); }); - it('should return an ETH withdraw transaction with paymaster parameters', async () => { + it('should return a withdraw transaction of the base token with paymaster parameters', async () => { const tx = { - from: ADDRESS, + from: ADDRESS1, value: 7_000_000_000n, - to: '0x000000000000000000000000000000000000800a', + to: utils.L2_BASE_TOKEN_ADDRESS, data: '0x51cff8d900000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049', customData: { paymasterParams: { @@ -400,13 +414,13 @@ describe('Provider', () => { }, }; const result = await provider.getWithdrawTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), @@ -416,23 +430,23 @@ describe('Provider', () => { it('should return a DAI withdraw transaction', async () => { const tx = { - from: ADDRESS, - to: (await provider.getDefaultBridgeAddresses()).erc20L2, + from: ADDRESS1, + to: (await provider.getDefaultBridgeAddresses()).sharedL2, data: '0xd9caed1200000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc04900000000000000000000000082b5ea13260346f4251c0940067a9117a6cf13840000000000000000000000000000000000000000000000000000000000000005', }; const result = await provider.getWithdrawTx({ token: await provider.l2TokenAddress(DAI_L1), amount: 5, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, }); expect(result).to.be.deepEqualExcluding(tx, ['data']); }); it('should return a DAI withdraw transaction with paymaster parameters', async () => { const tx = { - from: ADDRESS, - to: (await provider.getDefaultBridgeAddresses()).erc20L2, + from: ADDRESS1, + to: (await provider.getDefaultBridgeAddresses()).sharedL2, data: '0xd9caed1200000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc04900000000000000000000000082b5ea13260346f4251c0940067a9117a6cf13840000000000000000000000000000000000000000000000000000000000000005', customData: { paymasterParams: { @@ -445,11 +459,11 @@ describe('Provider', () => { const result = await provider.getWithdrawTx({ token: await provider.l2TokenAddress(DAI_L1), amount: 5, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), @@ -459,15 +473,15 @@ describe('Provider', () => { it('should return a withdraw transaction with `tx.from==tx.to` when `tx.to` is not provided', async () => { const tx = { - from: ADDRESS, + from: ADDRESS1, value: 7_000_000_000n, - to: '0x000000000000000000000000000000000000800a', + to: utils.L2_BASE_TOKEN_ADDRESS, data: '0x51cff8d900000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049', }; const result = await provider.getWithdrawTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - from: ADDRESS, + from: ADDRESS1, }); expect(result).to.be.deep.equal(tx); }); @@ -475,7 +489,7 @@ describe('Provider', () => { it('should throw an error when `tx.to` and `tx.from` are not provided`', async () => { try { await provider.getWithdrawTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 5, }); } catch (e) { @@ -486,10 +500,10 @@ describe('Provider', () => { it('should throw an error when `tx.amount!=tx.overrides.value', async () => { try { await provider.getWithdrawTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 5, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, overrides: {value: 7}, }); } catch (e) { @@ -503,15 +517,15 @@ describe('Provider', () => { describe('#getTransferTx()', () => { it('should return an ETH transfer transaction', async () => { const tx = { - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 7_000_000_000, }; const result = await provider.getTransferTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, }); expect(result).to.be.deep.equal(tx); }); @@ -519,8 +533,8 @@ describe('Provider', () => { it('should return an ETH transfer transaction with paymaster parameters', async () => { const tx = { type: utils.EIP712_TX_TYPE, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 7_000_000_000, customData: { paymasterParams: { @@ -531,13 +545,13 @@ describe('Provider', () => { }, }; const result = await provider.getTransferTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), @@ -547,22 +561,22 @@ describe('Provider', () => { it('should return a DAI transfer transaction', async () => { const tx = { - from: ADDRESS, + from: ADDRESS1, to: await provider.l2TokenAddress(DAI_L1), data: '0xa9059cbb000000000000000000000000a61464658afeaf65cccaafd3a512b69a83b776180000000000000000000000000000000000000000000000000000000000000005', }; const result = await provider.getTransferTx({ token: await provider.l2TokenAddress(DAI_L1), amount: 5, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, }); expect(result).to.be.deep.equal(tx); }); it('should return a DAI transfer transaction with paymaster parameters', async () => { const tx = { - from: ADDRESS, + from: ADDRESS1, to: await provider.l2TokenAddress(DAI_L1), data: '0xa9059cbb000000000000000000000000a61464658afeaf65cccaafd3a512b69a83b776180000000000000000000000000000000000000000000000000000000000000005', customData: { @@ -576,11 +590,11 @@ describe('Provider', () => { const result = await provider.getTransferTx({ token: await provider.l2TokenAddress(DAI_L1), amount: 5, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), @@ -592,23 +606,26 @@ describe('Provider', () => { describe('#estimateGasWithdraw()', () => { it('should return a gas estimation of the withdraw transaction', async () => { const result = await provider.estimateGasWithdraw({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, }); expect(result > 0).to.be.true; }); it('should return a gas estimation of the withdraw transaction with paymaster', async () => { + const token = IS_ETH_BASED + ? utils.ETH_ADDRESS_IN_CONTRACTS + : await wallet.l2TokenAddress(utils.ETH_ADDRESS_IN_CONTRACTS); const result = await provider.estimateGasWithdraw({ - token: utils.ETH_ADDRESS, + token: token, amount: 7_000_000_000, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), @@ -620,23 +637,23 @@ describe('Provider', () => { describe('#estimateGasTransfer()', () => { it('should return a gas estimation of the transfer transaction', async () => { const result = await provider.estimateGasTransfer({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, }); expect(result > 0).to.be.be.true; }); it('should return a gas estimation of the transfer transaction with paymaster', async () => { const result = await provider.estimateGasTransfer({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), @@ -648,8 +665,8 @@ describe('Provider', () => { describe('#estimateGasL1()', () => { it('should return a gas estimation of the L1 transaction', async () => { const result = await provider.estimateGasL1({ - from: ADDRESS, - to: await provider.getMainContractAddress(), + from: ADDRESS1, + to: await provider.getBridgehubContractAddress(), value: 7_000_000_000, customData: { gasPerPubdata: 800, @@ -662,9 +679,9 @@ describe('Provider', () => { describe('#estimateL1ToL2Execute()', () => { it('should return a gas estimation of the L1 to L2 transaction', async () => { const result = await provider.estimateL1ToL2Execute({ - contractAddress: await provider.getMainContractAddress(), + contractAddress: await provider.getBridgehubContractAddress(), calldata: '0x', - caller: ADDRESS, + caller: ADDRESS1, l2Value: 7_000_000_000, }); expect(result > 0).to.be.true; @@ -674,8 +691,8 @@ describe('Provider', () => { describe('#estimateFee()', () => { it('should return a gas estimation of the transaction', async () => { const result = await provider.estimateFee({ - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: `0x${7_000_000_000n.toString(16)}`, }); expect(result).not.to.be.null; @@ -685,18 +702,18 @@ describe('Provider', () => { describe('#estimateGas()', () => { it('should return a gas estimation of the transaction', async () => { const result = await provider.estimateGas({ - from: ADDRESS, + from: ADDRESS1, to: await provider.l2TokenAddress(DAI_L1), - data: utils.IERC20.encodeFunctionData('approve', [RECEIVER, 1]), + data: utils.IERC20.encodeFunctionData('approve', [ADDRESS2, 1]), }); expect(result > 0).to.be.true; }); it('should return a gas estimation of the EIP712 transaction', async () => { const result = await provider.estimateGas({ - from: ADDRESS, + from: ADDRESS1, to: await provider.l2TokenAddress(DAI_L1), - data: utils.IERC20.encodeFunctionData('approve', [RECEIVER, 1]), + data: utils.IERC20.encodeFunctionData('approve', [ADDRESS2, 1]), customData: { gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, }, @@ -708,7 +725,7 @@ describe('Provider', () => { describe('#getFilterChanges()', () => { it('should return the filtered logs', async () => { const filter = await provider.newFilter({ - address: utils.L2_ETH_TOKEN_ADDRESS, + address: utils.L2_BASE_TOKEN_ADDRESS, topics: [ethers.id('Transfer(address,address,uint256)')], }); const result = await provider.getFilterChanges(filter); diff --git a/tests/integration/signer.test.ts b/tests/integration/signer.test.ts index f18b9a71..bc459222 100644 --- a/tests/integration/signer.test.ts +++ b/tests/integration/signer.test.ts @@ -2,30 +2,39 @@ import * as chai from 'chai'; import '../custom-matchers'; import {Provider, utils, Wallet, L2VoidSigner, L1VoidSigner} from '../../src'; import {ethers} from 'ethers'; +import {IS_ETH_BASED, ADDRESS1, PRIVATE_KEY1, ADDRESS2, DAI_L1} from '../utils'; +import { + expectBigNumberCloseTo, + expectFeeDataCloseToExpected, +} from '../custom-matchers'; const {expect} = chai; -import TokensL1 from '../files/tokens.json'; +import {ITestnetERC20Token__factory} from '../../typechain'; describe('L2VoidSigner', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(); - const signer = new L2VoidSigner(ADDRESS, provider); + const signer = new L2VoidSigner(ADDRESS1, provider); + + let baseToken: string; + + before('setup', async function () { + this.timeout(25_000); + baseToken = await provider.getBaseTokenContractAddress(); + }); describe('#constructor()', () => { it('`L2VoidSigner(address, provider)` should return a `L2VoidSigner` with L2 provider', async () => { - const signer = new L2VoidSigner(ADDRESS, provider); + const signer = new L2VoidSigner(ADDRESS1, provider); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.equal(provider); }); it('`L2VoidSigner(address)` should return a `L2VoidSigner` without L2 provider', async () => { - const signer = new L2VoidSigner(ADDRESS); + const signer = new L2VoidSigner(ADDRESS1); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.null; }); }); @@ -40,7 +49,8 @@ describe('L2VoidSigner', () => { describe('#getAllBalances()', () => { it('should return all balances', async () => { const result = await signer.getAllBalances(); - expect(Object.keys(result)).to.have.lengthOf(2); + const expected = IS_ETH_BASED ? 2 : 3; + expect(Object.keys(result)).to.have.lengthOf(expected); }); }); @@ -54,16 +64,16 @@ describe('L2VoidSigner', () => { describe('#getAddress()', () => { it('should return a `L2VoidSigner` address', async () => { const result = await signer.getAddress(); - expect(result).to.be.equal(ADDRESS); + expect(result).to.be.equal(ADDRESS1); }); }); describe('#connect()', () => { it('should return a `L2VoidSigner` with provided `provider` as L2 provider', async () => { - let signer = new L2VoidSigner(ADDRESS); + let signer = new L2VoidSigner(ADDRESS1); signer = signer.connect(provider); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.equal(provider); }); }); @@ -78,17 +88,17 @@ describe('L2VoidSigner', () => { describe('#populateTransaction()', () => { it('should return populated transaction with default values if are omitted', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 270n, - maxFeePerGas: 1_500_000_000n, + maxFeePerGas: 1_200_000_000n, maxPriorityFeePerGas: 1_000_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); @@ -96,10 +106,10 @@ describe('L2VoidSigner', () => { it('should return populated transaction when `maxFeePerGas` and `maxPriorityFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), data: '0x', chainId: 270n, @@ -111,7 +121,7 @@ describe('L2VoidSigner', () => { }, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -125,10 +135,10 @@ describe('L2VoidSigner', () => { it('should return populated transaction when `maxPriorityFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), data: '0x', chainId: 270n, @@ -139,7 +149,7 @@ describe('L2VoidSigner', () => { }, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxPriorityFeePerGas: 2_000_000_000n, customData: { @@ -151,10 +161,10 @@ describe('L2VoidSigner', () => { it('should return populated transaction when `maxFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), data: '0x', chainId: 270n, @@ -165,7 +175,7 @@ describe('L2VoidSigner', () => { }, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, customData: { @@ -177,17 +187,17 @@ describe('L2VoidSigner', () => { it('should return populated EIP1559 transaction when `maxFeePerGas` and `maxPriorityFeePerGas` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 270n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -197,17 +207,17 @@ describe('L2VoidSigner', () => { it('should return populated EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas` same as provided `gasPrice`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 270n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 3_500_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, gasPrice: 3_500_000_000n, }); @@ -216,17 +226,17 @@ describe('L2VoidSigner', () => { it('should return populated legacy transaction when `type = 0`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 0, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 270n, - gasPrice: 250_000_000n, + gasPrice: 100_000_000n, }; const result = await signer.populateTransaction({ type: 0, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); @@ -237,7 +247,7 @@ describe('L2VoidSigner', () => { it('should throw an error when trying to send transaction', async () => { try { await signer.sendTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -254,7 +264,7 @@ describe('L2VoidSigner', () => { it('should throw an error when tyring to withdraw assets', async () => { try { await signer.withdraw({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, to: await signer.getAddress(), amount: 7_000_000_000, }); @@ -270,8 +280,8 @@ describe('L2VoidSigner', () => { it('should throw an error when tyring to transfer assets', async () => { try { await signer.transfer({ - token: utils.ETH_ADDRESS, - to: RECEIVER, + token: baseToken, + to: ADDRESS2, amount: 7_000_000_000, }); } catch (e) { @@ -287,7 +297,7 @@ describe('L2VoidSigner', () => { try { await signer.signTransaction({ type: 2, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000n, }); } catch (e) { @@ -299,37 +309,41 @@ describe('L2VoidSigner', () => { }); }); -describe('L1VoidSigner', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - +describe('L1VoidSigner', async () => { const provider = Provider.getDefaultProvider(); const ethProvider = ethers.getDefaultProvider('http://localhost:8545'); - const signer = new L1VoidSigner(ADDRESS, ethProvider, provider); + const signer = new L1VoidSigner(ADDRESS1, ethProvider, provider); - const DAI_L1 = TokensL1[0].address; + const tolerancePercentage = 10; // 10% tolerance + + let baseToken: string; + + before('setup', async function () { + baseToken = await provider.getBaseTokenContractAddress(); + this.timeout(25_000); + }); describe('#constructor()', () => { it('`L1VoidSigner(privateKey, providerL1, providerL2)` should return a `L1VoidSigner` with L1 and L2 provider', async () => { - const signer = new L1VoidSigner(ADDRESS, ethProvider, provider); + const signer = new L1VoidSigner(ADDRESS1, ethProvider, provider); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.equal(ethProvider); expect(signer.providerL2).to.be.equal(provider); }); it('`L1VoidSigner(privateKey, providerL1)` should return a `L1VoidSigner` with L1 provider', async () => { - const signer = new L1VoidSigner(ADDRESS, ethProvider); + const signer = new L1VoidSigner(ADDRESS1, ethProvider); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.equal(ethProvider); expect(signer.providerL2).to.be.undefined; }); it('`L1VoidSigner(privateKey)` should return a `L1VoidSigner` without providers', async () => { - const signer = new L1VoidSigner(ADDRESS); + const signer = new L1VoidSigner(ADDRESS1); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.null; expect(signer.providerL2).to.be.undefined; }); @@ -365,20 +379,27 @@ describe('L1VoidSigner', () => { describe('#l2TokenAddress()', () => { it('should return the L2 ETH address', async () => { - const result = await signer.l2TokenAddress(utils.ETH_ADDRESS); - expect(result).to.be.equal(utils.ETH_ADDRESS); + const result = await signer.l2TokenAddress(baseToken); + expect(result).to.be.equal(utils.L2_BASE_TOKEN_ADDRESS); }); it('should return the L2 DAI address', async () => { const result = await signer.l2TokenAddress(DAI_L1); expect(result).not.to.be.null; }); + + if (!IS_ETH_BASED) { + it('should return the L2 ETH address', async () => { + const result = await signer.l2TokenAddress(utils.LEGACY_ETH_ADDRESS); + expect(result).not.to.be.null; + }); + } }); describe('#approveERC20()', () => { it('should throw an error when approving token', async () => { try { - await signer.approveERC20(utils.ETH_ADDRESS, 5); + await signer.approveERC20(utils.LEGACY_ETH_ADDRESS, 5); } catch (e) { expect((e as Error).message).to.be.equal( "ETH token can't be approved! The address of the token does not exist on L1." @@ -404,24 +425,24 @@ describe('L1VoidSigner', () => { describe('#getAddress()', () => { it('should return a `L1VoidSigner` address', async () => { const result = await signer.getAddress(); - expect(result).to.be.equal(ADDRESS); + expect(result).to.be.equal(ADDRESS1); }); }); describe('#connect()', () => { it('should return a `L1VoidSigner` with provided `provider` as L1 provider', async () => { - let singer = new L1VoidSigner(ADDRESS); + let singer = new L1VoidSigner(ADDRESS1); singer = singer.connect(ethProvider); - expect(singer.address).to.be.equal(ADDRESS); + expect(singer.address).to.be.equal(ADDRESS1); expect(singer.provider).to.be.equal(ethProvider); }); }); describe('#connectL2()', () => { it('should return a `L1VoidSigner` with provided `provider` as L2 provider', async () => { - let singer = new L1VoidSigner(ADDRESS); + let singer = new L1VoidSigner(ADDRESS1); singer = singer.connectToL2(provider); - expect(singer.address).to.be.equal(ADDRESS); + expect(singer.address).to.be.equal(ADDRESS1); expect(singer.providerL2).to.be.equal(provider); }); }); @@ -429,17 +450,17 @@ describe('L1VoidSigner', () => { describe('#populateTransaction()', () => { it('should return populated transaction with default values if are omitted', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 9n, - maxFeePerGas: 1_500_000_014n, - maxPriorityFeePerGas: 1_500_000_000n, + maxFeePerGas: 1_000_000_002n, + maxPriorityFeePerGas: 1_000_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); @@ -447,17 +468,17 @@ describe('L1VoidSigner', () => { it('should return populated EIP1559 transaction when `maxFeePerGas` and `maxPriorityFeePerGas` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 9n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -467,17 +488,17 @@ describe('L1VoidSigner', () => { it('should return populated EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas` same as provided `gasPrice`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 9n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 3_500_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, gasPrice: 3_500_000_000n, }); @@ -486,17 +507,17 @@ describe('L1VoidSigner', () => { it('should return populated legacy transaction when `type = 0`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 0, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 9n, - gasPrice: 1_500_000_007n, + gasPrice: 1000000001n, }; const result = await signer.populateTransaction({ type: 0, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); @@ -507,7 +528,7 @@ describe('L1VoidSigner', () => { it('should throw an error when trying to send transaction', async () => { try { await signer.sendTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -521,114 +542,267 @@ describe('L1VoidSigner', () => { }); describe('#getDepositTx()', () => { - it('should return ETH deposit transaction', async () => { - const tx = { - contractAddress: ADDRESS, - calldata: '0x', - l2Value: 7_000_000, - l2GasLimit: '0x8cbaa', - token: '0x0000000000000000000000000000000000000000', - to: ADDRESS, - amount: 7_000_000, - refundRecipient: ADDRESS, - operatorTip: 0, - overrides: { - from: ADDRESS, - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - value: 288_213_007_000_000n, - }, - gasPerPubdataByte: 800, - }; - const result = await signer.getDepositTx({ - token: utils.ETH_ADDRESS, - to: await signer.getAddress(), - amount: 7_000_000, - refundRecipient: await signer.getAddress(), + if (IS_ETH_BASED) { + it('should return ETH deposit transaction', async () => { + const tx = { + contractAddress: ADDRESS1, + calldata: '0x', + l2Value: 7_000_000, + l2GasLimit: '0x56d78', + mintValue: 93_372_307_000_000n, + token: utils.ETH_ADDRESS_IN_CONTRACTS, + to: ADDRESS1, + amount: 7_000_000, + refundRecipient: ADDRESS1, + operatorTip: 0, + overrides: { + from: ADDRESS1, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 93_372_307_000_000n, + }, + gasPerPubdataByte: 800, + }; + const result = await signer.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + to: await signer.getAddress(), + amount: 7_000_000, + refundRecipient: await signer.getAddress(), + }); + expect(result).to.be.deep.equal(tx); }); - expect(result).to.be.deep.equal(tx); - }); - it('should return a deposit transaction with `tx.to == L1VoidSigner.getAddress()` when `tx.to` is not specified', async () => { - const tx = { - contractAddress: ADDRESS, - calldata: '0x', - l2Value: 7_000_000, - l2GasLimit: '0x8cbaa', - token: '0x0000000000000000000000000000000000000000', - to: ADDRESS, - amount: 7_000_000, - refundRecipient: ADDRESS, - operatorTip: 0, - overrides: { - from: ADDRESS, - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - value: 288_213_007_000_000n, - }, - gasPerPubdataByte: 800, - }; - const result = await signer.getDepositTx({ - token: utils.ETH_ADDRESS, - amount: 7_000_000, - refundRecipient: await signer.getAddress(), + it('should return a deposit transaction with `tx.to == Wallet.getAddress()` when `tx.to` is not specified', async () => { + const tx = { + contractAddress: ADDRESS1, + calldata: '0x', + l2Value: 7_000_000, + l2GasLimit: '0x56d78', + mintValue: 93_372_307_000_000n, + token: utils.ETH_ADDRESS_IN_CONTRACTS, + to: ADDRESS1, + amount: 7_000_000, + refundRecipient: ADDRESS1, + operatorTip: 0, + overrides: { + from: ADDRESS1, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 93_372_307_000_000n, + }, + gasPerPubdataByte: 800, + }; + const result = await signer.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + amount: 7_000_000, + refundRecipient: await signer.getAddress(), + }); + expect(result).to.be.deep.equal(tx); }); - expect(result).to.be.deep.equal(tx); - }); - it('should return DAI deposit transaction', async () => { - const tx = { - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - value: 288_992_000_000_000n, - from: ADDRESS, - to: await (await signer.getL1BridgeContracts()).erc20.getAddress(), - }; - const result = await signer.getDepositTx({ - token: DAI_L1, - to: await signer.getAddress(), - amount: 5, - refundRecipient: await signer.getAddress(), + it('should return DAI deposit transaction', async () => { + const tx = { + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 105_100_275_000_000n, + from: ADDRESS1, + to: await provider.getBridgehubContractAddress(), + }; + const result = await signer.getDepositTx({ + token: DAI_L1, + to: await signer.getAddress(), + amount: 5, + refundRecipient: await signer.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, ['data']); }); - expect(result).to.be.deepEqualExcluding(tx, ['data']); - }); + } else { + it('should return ETH deposit transaction', async () => { + const tx = { + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + value: 7_000_000n, + data: '0x24fd57fb0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010e0000000000000000000000000000000000000000000000000000bf1aaa17ee7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062e3d000000000000000000000000000000000000000000000000000000000000032000000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049000000000000000000000000842deab39809094bf5e4b77a7f97ae308adc5e5500000000000000000000000000000000000000000000000000000000006acfc0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049', + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + }; + const result = await signer.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + to: await signer.getAddress(), + amount: 7_000_000, + refundRecipient: await signer.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, ['data']); + }); + + it('should return a deposit transaction with `tx.to == Wallet.getAddress()` when `tx.to` is not specified', async () => { + const tx = { + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + value: 7_000_000n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1000_000_000n, + }; + const result = await signer.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + amount: 7_000_000, + refundRecipient: await signer.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, ['data']); + }); + + it('should return DAI deposit transaction', async () => { + const tx = { + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 0n, + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + }; + const result = await signer.getDepositTx({ + token: DAI_L1, + to: await signer.getAddress(), + amount: 5, + refundRecipient: await signer.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, ['data']); + }); + } }); describe('#estimateGasDeposit()', () => { - it('should return gas estimation for ETH deposit transaction', async () => { - const result = await signer.estimateGasDeposit({ - token: utils.ETH_ADDRESS, - to: await signer.getAddress(), - amount: 5, - refundRecipient: await signer.getAddress(), - }); - expect(result).to.be.equal(132_711n); - }); - - it('should return gas estimation for DAI deposit transaction', async () => { - const wallet = new Wallet( - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110', - provider, - ethProvider - ); - const tx = await wallet.approveERC20(DAI_L1, 5); - await tx.wait(); - - const result = await signer.estimateGasDeposit({ - token: DAI_L1, - to: await signer.getAddress(), - amount: 5, - refundRecipient: await signer.getAddress(), + if (IS_ETH_BASED) { + it('should return gas estimation for ETH deposit transaction', async () => { + const result = await signer.estimateGasDeposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await signer.getAddress(), + amount: 5, + refundRecipient: await signer.getAddress(), + }); + expectBigNumberCloseTo(result, 225_078n, tolerancePercentage); }); - expect(result).to.be.equal(253_418n); - }).timeout(10_000); + + it('should return gas estimation for DAI deposit transaction', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + await (await wallet.approveERC20(DAI_L1, 5)).wait(); + + const result = await signer.estimateGasDeposit({ + token: DAI_L1, + to: await signer.getAddress(), + amount: 5, + refundRecipient: await signer.getAddress(), + }); + expectBigNumberCloseTo(result, 338_196n, tolerancePercentage); + }).timeout(10_000); + } else { + it('should throw an error for insufficient allowance when estimating gas for ETH deposit transaction', async () => { + try { + await signer.estimateGasDeposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await signer.getAddress(), + amount: 5, + refundRecipient: await signer.getAddress(), + }); + } catch (e) { + expect((e as any).reason).to.include('ERC20: insufficient allowance'); + } + }).timeout(10_000); + + it('should return gas estimation for ETH deposit transaction', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const token = utils.LEGACY_ETH_ADDRESS; + const amount = 5; + const approveParams = await signer.getDepositAllowanceParams( + token, + amount + ); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await signer.estimateGasDeposit({ + token: token, + to: await signer.getAddress(), + amount: amount, + refundRecipient: await signer.getAddress(), + }); + expect(result > 0).to.be.true; + }).timeout(10_000); + + it('should return gas estimation for base token deposit transaction', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const token = await signer.getBaseToken(); + const amount = 5; + const approveParams = await signer.getDepositAllowanceParams( + token, + amount + ); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await signer.estimateGasDeposit({ + token: token, + to: await signer.getAddress(), + amount: amount, + refundRecipient: await signer.getAddress(), + }); + expect(result > 0).to.be.true; + }).timeout(10_000); + + it('should return gas estimation for DAI deposit transaction', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const token = DAI_L1; + const amount = 5; + const approveParams = await signer.getDepositAllowanceParams( + token, + amount + ); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + await ( + await wallet.approveERC20( + approveParams[1].token, + approveParams[1].allowance + ) + ).wait(); + + const result = await signer.estimateGasDeposit({ + token: token, + to: await signer.getAddress(), + amount: amount, + refundRecipient: await signer.getAddress(), + }); + expectBigNumberCloseTo(result, 361_501n, tolerancePercentage); + }).timeout(10_000); + } }); describe('#deposit()', () => { it('should throw an error when trying to deposit assets', async () => { try { await signer.deposit({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, to: await signer.getAddress(), amount: 7_000_000_000, refundRecipient: await signer.getAddress(), @@ -645,7 +819,7 @@ describe('L1VoidSigner', () => { it('should throw an error when trying to claim successful deposit', async () => { try { const response = await signer.deposit({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, to: await signer.getAddress(), amount: 7_000_000_000, refundRecipient: await signer.getAddress(), @@ -662,114 +836,343 @@ describe('L1VoidSigner', () => { }); describe('#getFullRequiredDepositFee()', () => { - it('should return fee for ETH token deposit', async () => { - const feeData = { - baseCost: 285_096_500_000_000n, - l1GasLimit: 132_711n, - l2GasLimit: '0x8b351', - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - }; - const result = await signer.getFullRequiredDepositFee({ - token: utils.ETH_ADDRESS, - to: await signer.getAddress(), - }); - expect(result).to.be.deep.equal(feeData); - }); - - it('should throw an error when there is not enough allowance to cover the deposit', async () => { - try { - await signer.getFullRequiredDepositFee({ - token: DAI_L1, + if (IS_ETH_BASED) { + it('should return fee for ETH token deposit', async () => { + const fee = { + baseCost: 95_595_450_000_000n, + l1GasLimit: 225_079n, + l2GasLimit: 355_704n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + }; + const result = await signer.getFullRequiredDepositFee({ + token: utils.LEGACY_ETH_ADDRESS, to: await signer.getAddress(), }); - } catch (e) { - expect((e as Error).message).to.be.equal( - 'Not enough allowance to cover the deposit!' - ); - } - }).timeout(10_000); - - it('should return fee for DAI token deposit', async () => { - const feeData = { - baseCost: 288_992_000_000_000n, - l1GasLimit: 253_177n, - l2GasLimit: '0x8d1c0', - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - }; - - const result = await signer.getFullRequiredDepositFee({ - token: DAI_L1, - to: await signer.getAddress(), + expectFeeDataCloseToExpected(result, fee, tolerancePercentage); }); - expect(result).to.be.deep.equal(feeData); - }).timeout(10_000); - it('should throw an error when there is not enough balance for the deposit', async () => { - try { + it('should throw an error when there is not enough allowance to cover the deposit', async () => { const randomSigner = new L1VoidSigner( - ethers.Wallet.createRandom().address, + Wallet.createRandom().address, ethProvider, provider ); - await randomSigner.getFullRequiredDepositFee({ - token: DAI_L1, + // transfer ETH to random signer so to avoid error: not enough balance + const transferTx = await new ethers.Wallet( + PRIVATE_KEY1, + ethProvider + ).sendTransaction({ to: await randomSigner.getAddress(), + value: ethers.parseEther('0.1'), }); - } catch (e) { - expect((e as Error).message).to.include( - 'Not enough balance for deposit!' + await transferTx.wait(); + + try { + await randomSigner.getFullRequiredDepositFee({ + token: DAI_L1, + to: await signer.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough allowance to cover the deposit!' + ); + } + }).timeout(10_000); + + it('should return fee for DAI token deposit', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const fee = { + baseCost: 107_602_662_500_000n, + l1GasLimit: 337_820n, + l2GasLimit: 400_382n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + }; + + const tx = await wallet.approveERC20(DAI_L1, 5); + await tx.wait(); + + const result = await signer.getFullRequiredDepositFee({ + token: DAI_L1, + to: await signer.getAddress(), + }); + expectFeeDataCloseToExpected(result, fee, tolerancePercentage); + }).timeout(10_000); + + it('should throw an error when there is not enough balance for the deposit', async () => { + try { + await new L1VoidSigner( + ethers.Wallet.createRandom().address, + ethProvider, + provider + ).getFullRequiredDepositFee({ + token: DAI_L1, + to: await signer.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.include( + 'Not enough balance for deposit!' + ); + } + }).timeout(10_000); + } else { + it('should throw an error when there is not enough base token allowance to cover the deposit', async () => { + try { + await new L1VoidSigner( + ethers.Wallet.createRandom().address, + ethProvider, + provider + ).getFullRequiredDepositFee({ + token: utils.LEGACY_ETH_ADDRESS, + to: await signer.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough base token allowance to cover the deposit!' + ); + } + }).timeout(10_000); + + it('should return fee for ETH token deposit', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const fee = { + baseCost: 111_540_656_250_000n, + l1GasLimit: 321_051n, + l2GasLimit: 415_035n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + }; + const token = utils.LEGACY_ETH_ADDRESS; + const approveParams = await signer.getDepositAllowanceParams(token, 1); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await signer.getFullRequiredDepositFee({ + token: token, + to: await signer.getAddress(), + }); + expectFeeDataCloseToExpected(result, fee, tolerancePercentage); + }).timeout(10_000); + + it('should return fee for base token deposit', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + const token = await signer.getBaseToken(); + const approveParams = await signer.getDepositAllowanceParams(token, 1); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await signer.getFullRequiredDepositFee({ + token: token, + to: await signer.getAddress(), + }); + expect(result).not.to.be.null; + }).timeout(10_000); + + it('should return fee for DAI token deposit', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const fee = { + baseCost: 107_602_662_500_000n, + l1GasLimit: 361_124n, + l2GasLimit: 400_382n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + }; + const token = DAI_L1; + const approveParams = await signer.getDepositAllowanceParams(token, 1); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + await ( + await wallet.approveERC20( + approveParams[1].token, + approveParams[1].allowance + ) + ).wait(); + + const result = await signer.getFullRequiredDepositFee({ + token: token, + to: await signer.getAddress(), + }); + expectFeeDataCloseToExpected(result, fee, tolerancePercentage); + }).timeout(10_000); + + it('should throw an error when there is not enough token allowance to cover the deposit', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const token = DAI_L1; + const randomWallet = new Wallet( + Wallet.createRandom().signingKey, + provider, + ethProvider ); - } - }).timeout(10_000); + + // mint base token to random wallet + const baseToken = ITestnetERC20Token__factory.connect( + await wallet.getBaseToken(), + wallet._signerL1() + ); + const baseTokenMintTx = await baseToken.mint( + await randomWallet.getAddress(), + ethers.parseEther('0.5') + ); + await baseTokenMintTx.wait(); + + // transfer ETH to random wallet so that base token approval tx can be performed + const transferTx = await new ethers.Wallet( + PRIVATE_KEY1, + ethProvider + ).sendTransaction({ + to: await randomWallet.getAddress(), + value: ethers.parseEther('0.1'), + }); + await transferTx.wait(); + + const approveParams = await randomWallet.getDepositAllowanceParams( + token, + 1 + ); + // only approve base token + await ( + await randomWallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + try { + await new L1VoidSigner( + randomWallet.address, + ethProvider, + provider + ).getFullRequiredDepositFee({ + token: token, + to: await wallet.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough token allowance to cover the deposit!' + ); + } + }).timeout(20_000); + } }); describe('#getRequestExecuteTx()', () => { - it('should return request execute transaction', async () => { - const result = await signer.getRequestExecuteTx({ - contractAddress: await provider.getMainContractAddress(), - calldata: '0x', - l2Value: 7_000_000_000, + const amount = 7_000_000_000; + if (IS_ETH_BASED) { + it('should return request execute transaction', async () => { + const result = await signer.getRequestExecuteTx({ + contractAddress: await provider.getBridgehubContractAddress(), + calldata: '0x', + l2Value: amount, + }); + expect(result).not.to.be.null; }); - expect(result).not.to.be.null; - }); + } else { + it('should return request execute transaction', async () => { + const result = await signer.getRequestExecuteTx({ + contractAddress: await signer.getAddress(), + calldata: '0x', + l2Value: amount, + overrides: {nonce: 0}, + }); + expect(result).not.to.be.null; + }); + } }); describe('#estimateGasRequestExecute()', () => { it('should return gas estimation for request execute transaction', async () => { const result = await signer.estimateGasRequestExecute({ - contractAddress: await provider.getMainContractAddress(), + contractAddress: await provider.getBridgehubContractAddress(), calldata: '0x', l2Value: 7_000_000_000, }); - expect(result >= 0n).to.be.true; + expect(result > 0).to.be.true; }); }); describe('#requestExecute()', () => { - it('should request transaction execution on L2 network', async () => { - try { - await signer.requestExecute({ - contractAddress: await provider.getMainContractAddress(), + if (IS_ETH_BASED) { + it('should request transaction execution on L2 network', async () => { + try { + await signer.requestExecute({ + contractAddress: await provider.getBridgehubContractAddress(), + calldata: '0x', + l2Value: 7_000_000_000, + l2GasLimit: 900_000, + }); + } catch (e) { + expect((e as Error).message).to.contain( + 'VoidSigner cannot sign transactions' + ); + } + }).timeout(10_000); + } else { + it('should request transaction execution on L2 network', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const amount = 7_000_000_000; + const request = { + contractAddress: await signer.getAddress(), calldata: '0x', - l2Value: 7_000_000_000, - l2GasLimit: 900_000, - }); - } catch (e) { - expect((e as Error).message).to.contain( - 'VoidSigner cannot sign transactions' - ); - } - }).timeout(10_000); + l2Value: amount, + l2GasLimit: 1_319_957n, + operatorTip: 0, + gasPerPubdataByte: 800, + refundRecipient: await signer.getAddress(), + overrides: { + maxFeePerGas: 1_000_000_010n, + maxPriorityFeePerGas: 1_000_000_000n, + gasLimit: 238_654n, + value: 0, + }, + }; + + const approveParams = + await signer.getRequestExecuteAllowanceParams(request); + await ( + await wallet.approveERC20( + approveParams.token, + approveParams.allowance + ) + ).wait(); + + try { + await signer.requestExecute(request); + } catch (e) { + expect((e as Error).message).to.contain( + 'VoidSigner cannot sign transactions' + ); + } + }).timeout(10_000); + } }); describe('#signTransaction()', () => { it('should throw an error when trying to send transaction', async () => { try { await signer.sendTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, diff --git a/tests/integration/smart-account.test.ts b/tests/integration/smart-account.test.ts index 4c4666e0..90a26ae8 100644 --- a/tests/integration/smart-account.test.ts +++ b/tests/integration/smart-account.test.ts @@ -10,54 +10,59 @@ import { } from '../../src'; import {ethers} from 'ethers'; import {ECDSASmartAccount, MultisigECDSASmartAccount} from '../../src'; - +import { + IS_ETH_BASED, + ADDRESS1, + PRIVATE_KEY1, + ADDRESS2, + PRIVATE_KEY2, + DAI_L1, + APPROVAL_TOKEN, + PAYMASTER, +} from '../utils'; + +import {expectBigNumberCloseTo} from '../custom-matchers'; const {expect} = chai; -import TokensL1 from '../files/tokens.json'; import MultisigAccount from '../files/TwoUserMultisig.json'; describe('SmartAccount', async () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); const ethProvider = ethers.getDefaultProvider('http://localhost:8545'); - const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); const account = new SmartAccount( - {address: ADDRESS, secret: PRIVATE_KEY}, + {address: ADDRESS1, secret: PRIVATE_KEY1}, provider ); - const DAI_L1 = TokensL1[0].address; - - const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; - const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; + const tolerancePercentage = 10; // 10% tolerance describe('#constructor()', () => { it('`SmartAccount(address, {address, secret}, provider)` should return a `SmartAccount` with signer and provider', () => { const account = new SmartAccount( - {address: ADDRESS, secret: PRIVATE_KEY}, + {address: ADDRESS1, secret: PRIVATE_KEY1}, provider ); - expect(account.address).to.be.equal(ADDRESS); - expect(account.secret).to.be.equal(PRIVATE_KEY); + expect(account.address).to.be.equal(ADDRESS1); + expect(account.secret).to.be.equal(PRIVATE_KEY1); expect(account.provider).to.be.equal(provider); }); it('`SmartAccount(address, {address, secret})` should return a `SmartAccount` with signer', () => { - const account = new SmartAccount({address: ADDRESS, secret: PRIVATE_KEY}); - expect(account.address).to.be.equal(ADDRESS); - expect(account.secret).to.be.equal(PRIVATE_KEY); + const account = new SmartAccount({ + address: ADDRESS1, + secret: PRIVATE_KEY1, + }); + expect(account.address).to.be.equal(ADDRESS1); + expect(account.secret).to.be.equal(PRIVATE_KEY1); expect(account.provider).to.be.null; }); it('`SmartWallet(address, {address, secret, payloadSigner, transactionBuilder}, provider)` should return a `SmartAccount` with custom payload signing method', async () => { const account = new SmartAccount( { - address: ADDRESS, - secret: PRIVATE_KEY, + address: ADDRESS1, + secret: PRIVATE_KEY1, payloadSigner: async () => { return '0x'; }, @@ -68,8 +73,8 @@ describe('SmartAccount', async () => { provider ); - expect(account.address).to.be.equal(ADDRESS); - expect(account.secret).to.be.equal(PRIVATE_KEY); + expect(account.address).to.be.equal(ADDRESS1); + expect(account.secret).to.be.equal(PRIVATE_KEY1); expect(account.provider).to.be.equal(provider); }); }); @@ -78,23 +83,23 @@ describe('SmartAccount', async () => { it('should return a `SmartAccount` with provided `provider` as a provider', async () => { const newProvider = Provider.getDefaultProvider(types.Network.Localhost); let account = new SmartAccount( - {address: ADDRESS, secret: PRIVATE_KEY}, + {address: ADDRESS1, secret: PRIVATE_KEY1}, provider ); account = account.connect(newProvider); - expect(account.address).to.be.equal(ADDRESS); - expect(account.secret).to.be.equal(PRIVATE_KEY); + expect(account.address).to.be.equal(ADDRESS1); + expect(account.secret).to.be.equal(PRIVATE_KEY1); expect(account.provider).to.be.equal(newProvider); }); it('should return a `SmartAccount` with no `provider` when `null` is used', async () => { let account = new SmartAccount( - {address: ADDRESS, secret: PRIVATE_KEY}, + {address: ADDRESS1, secret: PRIVATE_KEY1}, provider ); account = account.connect(null); - expect(account.address).to.be.equal(ADDRESS); - expect(account.secret).to.be.equal(PRIVATE_KEY); + expect(account.address).to.be.equal(ADDRESS1); + expect(account.secret).to.be.equal(PRIVATE_KEY1); expect(account.provider).to.be.equal(null); }); }); @@ -102,11 +107,11 @@ describe('SmartAccount', async () => { describe('#getAddress()', () => { it('should return the `SmartAccount` address', async () => { const account = new SmartAccount( - {address: ADDRESS, secret: PRIVATE_KEY}, + {address: ADDRESS1, secret: PRIVATE_KEY1}, provider ); const result = await account.getAddress(); - expect(result).to.be.equal(ADDRESS); + expect(result).to.be.equal(ADDRESS1); }); }); @@ -120,7 +125,8 @@ describe('SmartAccount', async () => { describe('#getAllBalances()', () => { it('should return all balances', async () => { const result = await account.getAllBalances(); - expect(Object.keys(result)).to.have.lengthOf(2); + const expected = IS_ETH_BASED ? 2 : 3; + expect(Object.keys(result)).to.have.lengthOf(expected); }); }); @@ -134,40 +140,45 @@ describe('SmartAccount', async () => { describe('#populateTransaction()', () => { it('should return a populated transaction', async () => { const tx = { - to: '0xa61464658AfeAf65CccaaFD3a512b69A83B77618', + to: ADDRESS2, value: 7_000_000_000n, type: utils.EIP712_TX_TYPE, - from: '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049', + from: ADDRESS1, nonce: await account.getNonce('pending'), - gasLimit: 154_379n, + gasLimit: 156_726n, chainId: 270n, data: '0x', customData: {gasPerPubdata: 50_000, factoryDeps: []}, - gasPrice: 250_000_000n, + gasPrice: 100_000_000n, }; const result = await account.populateTransaction({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000, }); - expect(result).to.be.deep.equal(tx); + expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expectBigNumberCloseTo( + result.gasLimit as bigint, + tx.gasLimit, + tolerancePercentage + ); }).timeout(25_000); it('should return a populated transaction with default values if are omitted', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: utils.EIP712_TX_TYPE, - from: '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049', + from: ADDRESS1, nonce: await account.getNonce('pending'), chainId: 270n, - gasPrice: 250_000_000n, + gasPrice: 100_000_000n, data: '0x', customData: {gasPerPubdata: 50_000, factoryDeps: []}, }; const result = await account.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); @@ -177,7 +188,7 @@ describe('SmartAccount', async () => { describe('#signTransaction()', () => { it('should return a signed EIP712 transaction', async () => { const result = await account.signTransaction({ - to: RECEIVER, + to: ADDRESS2, value: ethers.parseEther('1'), }); expect(result).not.to.be.null; @@ -214,14 +225,14 @@ describe('SmartAccount', async () => { describe('#transfer()', () => { it('should transfer ETH', async () => { const amount = 7_000_000_000n; - const balanceBeforeTransfer = await provider.getBalance(RECEIVER); + const balanceBeforeTransfer = await provider.getBalance(ADDRESS2); const tx = await account.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: amount, }); const result = await tx.wait(); - const balanceAfterTransfer = await provider.getBalance(RECEIVER); + const balanceAfterTransfer = await provider.getBalance(ADDRESS2); expect(result).not.to.be.null; expect(balanceAfterTransfer - balanceBeforeTransfer).to.be.equal(amount); }).timeout(25_000); @@ -235,20 +246,20 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await account.getBalance(); const senderApprovalTokenBalanceBeforeTransfer = - await account.getBalance(TOKEN); - const receiverBalanceBeforeTransfer = await provider.getBalance(RECEIVER); + await account.getBalance(APPROVAL_TOKEN); + const receiverBalanceBeforeTransfer = await provider.getBalance(ADDRESS2); const tx = await account.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -260,12 +271,12 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await account.getBalance(); const senderApprovalTokenBalanceAfterTransfer = - await account.getBalance(TOKEN); - const receiverBalanceAfterTransfer = await provider.getBalance(RECEIVER); + await account.getBalance(APPROVAL_TOKEN); + const receiverBalanceAfterTransfer = await provider.getBalance(ADDRESS2); expect( paymasterBalanceBeforeTransfer - paymasterBalanceAfterTransfer >= 0n @@ -292,18 +303,18 @@ describe('SmartAccount', async () => { const amount = 5n; const l2DAI = await provider.l2TokenAddress(DAI_L1); const balanceBeforeTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); const tx = await account.transfer({ token: l2DAI, - to: RECEIVER, + to: ADDRESS2, amount: amount, }); const result = await tx.wait(); const balanceAfterTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); @@ -321,24 +332,24 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await account.getBalance(l2DAI); const senderApprovalTokenBalanceBeforeTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceBeforeTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); const tx = await account.transfer({ token: l2DAI, - to: RECEIVER, + to: ADDRESS2, amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -350,13 +361,13 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await account.getBalance(l2DAI); const senderApprovalTokenBalanceAfterTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceAfterTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); @@ -414,11 +425,11 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await account.getBalance(); const l2ApprovalTokenBalanceBeforeWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const withdrawTx = await account.withdraw({ token: utils.ETH_ADDRESS, @@ -426,7 +437,7 @@ describe('SmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -444,11 +455,11 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await account.getBalance(); const l2ApprovalTokenBalanceAfterWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0n @@ -509,12 +520,12 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await account.getBalance(l2DAI); const l1BalanceBeforeWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceBeforeWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const withdrawTx = await account.withdraw({ token: l2DAI, @@ -522,7 +533,7 @@ describe('SmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -540,12 +551,12 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await account.getBalance(l2DAI); const l1BalanceAfterWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceAfterWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0n @@ -571,23 +582,11 @@ describe('SmartAccount', async () => { }); describe('MultisigECDSASmartAccount', async () => { - const ADDRESS1 = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY1 = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const ADDRESS2 = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const PRIVATE_KEY2 = - '0xac1e735be8536c6534bb4f17f06f6afc73b2b5ba84ac2cfb12f7461b20c0bbe3'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); const ethProvider = ethers.getDefaultProvider('http://localhost:8545'); const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); let account: SmartAccount; - const DAI_L1 = TokensL1[0].address; - - const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; - const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; - before('setup', async function () { this.timeout(25_000); @@ -620,7 +619,7 @@ describe('MultisigECDSASmartAccount', async () => { // send paymaster approval token to multisig account const sendApprovalTokenTx = await deployer.transfer({ to: multisigAddress, - token: TOKEN, + token: APPROVAL_TOKEN, amount: 5, }); await sendApprovalTokenTx.wait(); @@ -664,11 +663,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await account.getBalance(); const senderApprovalTokenBalanceBeforeTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceBeforeTransfer = await provider.getBalance(ADDRESS2); const tx = await account.transfer({ @@ -677,7 +676,7 @@ describe('MultisigECDSASmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -689,11 +688,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await account.getBalance(); const senderApprovalTokenBalanceAfterTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceAfterTransfer = await provider.getBalance(ADDRESS2); expect( @@ -750,11 +749,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await account.getBalance(l2DAI); const senderApprovalTokenBalanceBeforeTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceBeforeTransfer = await provider.getBalance( ADDRESS2, 'latest', @@ -767,7 +766,7 @@ describe('MultisigECDSASmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -779,11 +778,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await account.getBalance(l2DAI); const senderApprovalTokenBalanceAfterTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceAfterTransfer = await provider.getBalance( ADDRESS2, 'latest', @@ -843,11 +842,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await account.getBalance(); const l2ApprovalTokenBalanceBeforeWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const withdrawTx = await account.withdraw({ token: utils.ETH_ADDRESS, @@ -855,7 +854,7 @@ describe('MultisigECDSASmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -873,11 +872,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await account.getBalance(); const l2ApprovalTokenBalanceAfterWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0 @@ -939,12 +938,12 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await account.getBalance(l2DAI); const l1BalanceBeforeWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceBeforeWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const withdrawTx = await account.withdraw({ token: l2DAI, @@ -952,7 +951,7 @@ describe('MultisigECDSASmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -970,12 +969,12 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await account.getBalance(l2DAI); const l1BalanceAfterWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceAfterWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0n diff --git a/tests/integration/types.test.ts b/tests/integration/types.test.ts index 4417b40e..37268b27 100644 --- a/tests/integration/types.test.ts +++ b/tests/integration/types.test.ts @@ -1,14 +1,11 @@ import {expect} from 'chai'; import '../custom-matchers'; import {Provider, types, utils, Wallet} from '../../src'; +import {ADDRESS2, PRIVATE_KEY1} from '../utils'; describe('types', () => { - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); - const wallet = new Wallet(PRIVATE_KEY, provider); + const wallet = new Wallet(PRIVATE_KEY1, provider); describe('TransactionResponse', () => { let tx: types.TransactionResponse; @@ -17,7 +14,7 @@ describe('types', () => { this.timeout(25_000); tx = await wallet.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: 1_000_000, }); await tx.wait(); @@ -52,7 +49,7 @@ describe('types', () => { this.timeout(25_000); const tx = await wallet.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: 1_000_000, }); await tx.wait(); @@ -88,7 +85,7 @@ describe('types', () => { this.timeout(25_000); const tx = await wallet.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: 1_000_000, }); await tx.wait(); @@ -132,7 +129,7 @@ describe('types', () => { this.timeout(25_000); const tx = await wallet.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: 1_000_000, }); await tx.wait(); @@ -191,14 +188,14 @@ describe('types', () => { this.timeout(25_000); const signedEip712Tx = await wallet.signTransaction({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, + to: ADDRESS2, value: 1_000_000, nonce: 1, }); eip712Tx = types.Transaction.from(signedEip712Tx); const signedLegacyTx = await wallet.signTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 1_000_000, nonce: 1, }); @@ -208,14 +205,14 @@ describe('types', () => { describe('#serialized()', () => { it('should return the serialized EIP1559 transaction', async () => { const tx = - '0x02f87082010e01843b9aca008459682f0083025de894a61464658afeaf65cccaafd3a512b69a83b77618830f424080c080a09b9cfb09599c0e632deb3954505234448edaef0bae4776a88473692343d0013da035c2825459b717aa827569a4dd4077dcf4e35cb24a12fbdfcfa46be24bd271ae'; + '0x02f87082010e01843b9aca008447868c0083026e1f94a61464658afeaf65cccaafd3a512b69a83b77618830f424080c001a0b0131078e3635ea6366cba74053b7df981e317ec5f05fc5107a31c2b5769435aa03ecbe41ddc7a5b2a6814c9d93222d339951848b678d66333ff1416ac3f16b7ff'; const result = eip1559Tx.serialized; expect(result).to.be.equal(tx); }); it('should return the serialized EIP712 transaction', async () => { const tx = - '0x71f88e01840ee6b280840ee6b28083025b0b94a61464658afeaf65cccaafd3a512b69a83b77618830f42408082010e808082010e9436615cf349d7f6344891b1e7ca7c72883f5dc04982c350c0b841de26c3845dd9032d8fb6e761c89e155181e3cbd12d4294fec4065dafaa8628af482ba6f5361aa016b5371b00ff5e8222a148ced3d485f3cba9d25c08761b25b51cc0'; + '0x71f88e018405f5e1008405f5e1008302658a94a61464658afeaf65cccaafd3a512b69a83b77618830f42408082010e808082010e9436615cf349d7f6344891b1e7ca7c72883f5dc04982c350c0b8412058c9984aa8b1ff410286b17c6be2e8039058c75cf13edea577f6ee7d1b3b7943e579477c497eaa7d857654b73eea5d12d51a347ee8707389c811f3acf322851cc0'; const result = eip712Tx.serialized; expect(result).to.be.equal(tx); }); @@ -224,14 +221,14 @@ describe('types', () => { describe('#unsignedSerialized()', () => { it('should return the unsigned serialized EIP1559 transaction', async () => { const tx = - '0x02ed82010e01843b9aca008459682f0083025de894a61464658afeaf65cccaafd3a512b69a83b77618830f424080c0'; + '0x02ed82010e01843b9aca008447868c0083026e1f94a61464658afeaf65cccaafd3a512b69a83b77618830f424080c0'; const result = eip1559Tx.unsignedSerialized; expect(result).to.be.equal(tx); }); it('should return the unsigned serialized EIP712 transaction', async () => { const tx = - '0x71f88e01840ee6b280840ee6b28083025b0b94a61464658afeaf65cccaafd3a512b69a83b77618830f42408082010e808082010e9436615cf349d7f6344891b1e7ca7c72883f5dc04982c350c0b841de26c3845dd9032d8fb6e761c89e155181e3cbd12d4294fec4065dafaa8628af482ba6f5361aa016b5371b00ff5e8222a148ced3d485f3cba9d25c08761b25b51cc0'; + '0x71f88e018405f5e1008405f5e1008302658a94a61464658afeaf65cccaafd3a512b69a83b77618830f42408082010e808082010e9436615cf349d7f6344891b1e7ca7c72883f5dc04982c350c0b8412058c9984aa8b1ff410286b17c6be2e8039058c75cf13edea577f6ee7d1b3b7943e579477c497eaa7d857654b73eea5d12d51a347ee8707389c811f3acf322851cc0'; const result = eip712Tx.unsignedSerialized; expect(result).to.be.equal(tx); }); diff --git a/tests/integration/utils.test.ts b/tests/integration/utils.test.ts index 7391f34a..b5da1ea5 100644 --- a/tests/integration/utils.test.ts +++ b/tests/integration/utils.test.ts @@ -2,26 +2,23 @@ import * as chai from 'chai'; import '../custom-matchers'; import {Provider, types, utils, EIP712Signer} from '../../src'; import {ethers} from 'ethers'; +import {ADDRESS1, PRIVATE_KEY1} from '../utils'; const {expect} = chai; describe('utils', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); describe('#isMessageSignatureCorrect()', () => { it('should return true for a valid message signature', async () => { const message = 'Hello, world!'; - const signature = await new ethers.Wallet(PRIVATE_KEY).signMessage( + const signature = await new ethers.Wallet(PRIVATE_KEY1).signMessage( message ); const result = await utils.isMessageSignatureCorrect( provider, - ADDRESS, + ADDRESS1, message, signature ); @@ -35,7 +32,7 @@ describe('utils', () => { const result = await utils.isMessageSignatureCorrect( provider, - ADDRESS, + ADDRESS1, message, invalidSignature ); @@ -48,13 +45,13 @@ describe('utils', () => { const tx: types.TransactionRequest = { type: 113, chainId: 270, - from: ADDRESS, + from: ADDRESS1, to: '0xa61464658AfeAf65CccaaFD3a512b69A83B77618', value: 7_000_000n, }; const eip712Signer = new EIP712Signer( - new ethers.Wallet(PRIVATE_KEY), + new ethers.Wallet(PRIVATE_KEY1), Number((await provider.getNetwork()).chainId) ); @@ -62,7 +59,7 @@ describe('utils', () => { const result = await utils.isTypedDataSignatureCorrect( provider, - ADDRESS, + ADDRESS1, await eip712Signer.getDomain(), utils.EIP712_TYPES, EIP712Signer.getSignInput(tx), @@ -79,19 +76,19 @@ describe('utils', () => { const tx: types.TransactionRequest = { type: 113, chainId: 270, - from: ADDRESS, + from: ADDRESS1, to: '0xa61464658AfeAf65CccaaFD3a512b69A83B77618', value: 1_000_000n, }; const eip712Signer = new EIP712Signer( - new ethers.Wallet(PRIVATE_KEY), + new ethers.Wallet(PRIVATE_KEY1), Number((await provider.getNetwork()).chainId) ); const result = await utils.isTypedDataSignatureCorrect( provider, - ADDRESS, + ADDRESS1, await eip712Signer.getDomain(), utils.EIP712_TYPES, EIP712Signer.getSignInput(tx), diff --git a/tests/integration/wallet.test.ts b/tests/integration/wallet.test.ts index 3b1a0d9d..83777949 100644 --- a/tests/integration/wallet.test.ts +++ b/tests/integration/wallet.test.ts @@ -3,41 +3,43 @@ import '../custom-matchers'; import {Provider, types, utils, Wallet} from '../../src'; import {ethers} from 'ethers'; import * as fs from 'fs'; - +import {ITestnetERC20Token__factory} from '../../typechain'; +import { + IS_ETH_BASED, + ADDRESS1, + PRIVATE_KEY1, + MNEMONIC1, + ADDRESS2, + DAI_L1, + APPROVAL_TOKEN, + PAYMASTER, +} from '../utils'; + +import { + expectFeeDataCloseToExpected, + expectBigNumberCloseTo, +} from '../custom-matchers'; const {expect} = chai; -import TokensL1 from '../files/tokens.json'; -import CustomBridge from '../files/customBridge.json'; - describe('Wallet', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const MNEMONIC = - 'stuff slice staff easily soup parent arm payment cotton trade scatter struggle'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); const ethProvider = ethers.getDefaultProvider('http://localhost:8545'); - const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); - - const DAI_L1 = TokensL1[0].address; + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); - const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; - const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; + const tolerancePercentage = 10; // 10% tolerance describe('#constructor()', () => { it('`Wallet(privateKey, provider)` should return a `Wallet` with L2 provider', async () => { - const wallet = new Wallet(PRIVATE_KEY, provider); + const wallet = new Wallet(PRIVATE_KEY1, provider); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(wallet.provider).to.be.equal(provider); }); it('`Wallet(privateKey, provider, ethProvider)` should return a `Wallet` with L1 and L2 provider', async () => { - const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(wallet.provider).to.be.equal(provider); expect(wallet.providerL1).to.be.equal(ethProvider); }); @@ -50,6 +52,13 @@ describe('Wallet', () => { }); }); + describe('#getBridgehubContract()', () => { + it('should return the bridgehub contract', async () => { + const result = await wallet.getBridgehubContract(); + expect(result).not.to.be.null; + }); + }); + describe('#getL1BridgeContracts()', () => { it('should return the L1 bridge contracts', async () => { const result = await wallet.getL1BridgeContracts(); @@ -57,6 +66,22 @@ describe('Wallet', () => { }); }); + describe('#isETHBasedChain()', () => { + it('should return whether the chain is ETH-based or not', async () => { + const result = await wallet.isETHBasedChain(); + expect(result).to.be.equal(IS_ETH_BASED); + }); + }); + + describe('#getBaseToken()', () => { + it('should return base token', async () => { + const result = await wallet.getBaseToken(); + IS_ETH_BASED + ? expect(result).to.be.equal(utils.ETH_ADDRESS_IN_CONTRACTS) + : expect(result).not.to.be.null; + }); + }); + describe('#getBalanceL1()', () => { it('should return a L1 balance', async () => { const result = await wallet.getBalanceL1(); @@ -72,9 +97,17 @@ describe('Wallet', () => { }); describe('#l2TokenAddress()', () => { + it('should return the L2 base address', async () => { + const baseToken = await provider.getBaseTokenContractAddress(); + const result = await wallet.l2TokenAddress(baseToken); + expect(result).to.be.equal(utils.L2_BASE_TOKEN_ADDRESS); + }); + it('should return the L2 ETH address', async () => { - const result = await wallet.l2TokenAddress(utils.ETH_ADDRESS); - expect(result).to.be.equal(utils.ETH_ADDRESS); + if (!IS_ETH_BASED) { + const result = await wallet.l2TokenAddress(utils.LEGACY_ETH_ADDRESS); + expect(result).not.to.be.null; + } }); it('should return the L2 DAI address', async () => { @@ -92,7 +125,7 @@ describe('Wallet', () => { it('should throw an error when approving ETH token', async () => { try { - await wallet.approveERC20(utils.ETH_ADDRESS, 5); + await wallet.approveERC20(utils.LEGACY_ETH_ADDRESS, 5); } catch (e) { expect((e as Error).message).to.be.equal( "ETH token can't be approved! The address of the token does not exist on L1." @@ -118,7 +151,8 @@ describe('Wallet', () => { describe('#getAllBalances()', () => { it('should return the all balances', async () => { const result = await wallet.getAllBalances(); - expect(Object.keys(result)).to.have.lengthOf(2); + const expected = IS_ETH_BASED ? 2 : 3; + expect(Object.keys(result)).to.have.lengthOf(expected); }); }); @@ -132,25 +166,25 @@ describe('Wallet', () => { describe('#getAddress()', () => { it('should return the `Wallet` address', async () => { const result = await wallet.getAddress(); - expect(result).to.be.equal(ADDRESS); + expect(result).to.be.equal(ADDRESS1); }); }); describe('#ethWallet()', () => { it('should return a L1 `Wallet`', async () => { - const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); const ethWallet = wallet.ethWallet(); - expect(ethWallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(ethWallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(ethWallet.provider).to.be.equal(ethProvider); }); it('should throw an error when L1 `Provider` is not specified in constructor', async () => { - const wallet = new Wallet(PRIVATE_KEY, provider); + const wallet = new Wallet(PRIVATE_KEY1, provider); try { wallet.ethWallet(); } catch (e) { expect((e as Error).message).to.be.equal( - 'L1 provider missing: use `connectToL1` to specify!' + 'L1 provider is missing! Specify an L1 provider using `Wallet.connectToL1()`.' ); } }); @@ -158,18 +192,18 @@ describe('Wallet', () => { describe('#connect()', () => { it('should return a `Wallet` with provided `provider` as L2 provider', async () => { - let wallet = new Wallet(PRIVATE_KEY); + let wallet = new Wallet(PRIVATE_KEY1); wallet = wallet.connect(provider); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(wallet.provider).to.be.equal(provider); }); }); describe('#connectL1()', () => { it('should return a `Wallet` with provided `provider` as L1 provider', async () => { - let wallet = new Wallet(PRIVATE_KEY); + let wallet = new Wallet(PRIVATE_KEY1); wallet = wallet.connectToL1(ethProvider); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(wallet.providerL1).to.be.equal(ethProvider); }); }); @@ -184,50 +218,50 @@ describe('Wallet', () => { describe('#populateTransaction()', () => { it('should return a populated transaction', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000n, type: utils.EIP712_TX_TYPE, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), gasLimit: 154_379n, chainId: 270n, data: '0x', customData: {gasPerPubdata: 50_000, factoryDeps: []}, - gasPrice: 250_000_000n, + gasPrice: 100_000_000n, }; const result = await wallet.populateTransaction({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000, }); - expect(result).to.be.deep.equal(tx); + expect(result).to.be.deepEqualExcluding(tx, ['gasLimit', 'chainId']); }).timeout(25_000); it('should return a populated transaction with default values if are omitted', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), chainId: 270n, - maxFeePerGas: 1_500_000_000n, + maxFeePerGas: 1_200_000_000n, maxPriorityFeePerGas: 1_000_000_000n, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); - expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(result).to.be.deepEqualExcluding(tx, ['gasLimit', 'chainId']); }); it('should return populated transaction when `maxFeePerGas` and `maxPriorityFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), data: '0x', chainId: 270n, @@ -239,7 +273,7 @@ describe('Wallet', () => { }, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -253,10 +287,10 @@ describe('Wallet', () => { it('should return populated transaction when `maxPriorityFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), data: '0x', chainId: 270n, @@ -267,7 +301,7 @@ describe('Wallet', () => { }, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxPriorityFeePerGas: 2_000_000_000n, customData: { @@ -279,10 +313,10 @@ describe('Wallet', () => { it('should return populated transaction when `maxFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), data: '0x', chainId: 270n, @@ -293,7 +327,7 @@ describe('Wallet', () => { }, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, customData: { @@ -305,17 +339,17 @@ describe('Wallet', () => { it('should return populated EIP1559 transaction when `maxFeePerGas` and `maxPriorityFeePerGas` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), chainId: 270n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -325,17 +359,17 @@ describe('Wallet', () => { it('should return populated EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas` same as provided `gasPrice`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), chainId: 270n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 3_500_000_000n, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, gasPrice: 3_500_000_000n, }); @@ -344,17 +378,17 @@ describe('Wallet', () => { it('should return populated legacy transaction when `type = 0`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 0, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), chainId: 270n, - gasPrice: 250_000_000n, + gasPrice: 100_000_000n, }; const result = await wallet.populateTransaction({ type: 0, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); @@ -364,7 +398,7 @@ describe('Wallet', () => { describe('#sendTransaction()', () => { it('should send already populated transaction with provided `maxFeePerGas` and `maxPriorityFeePerGas` and `customData` fields', async () => { const populatedTx = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -379,7 +413,7 @@ describe('Wallet', () => { it('should send EIP1559 transaction when `maxFeePerGas` and `maxPriorityFeePerGas` are provided', async () => { const tx = await wallet.sendTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -389,9 +423,9 @@ describe('Wallet', () => { expect(result.type).to.be.equal(2); }).timeout(10_000); - it('should return already populated EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas`', async () => { + it('should send already populated EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas`', async () => { const populatedTx = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -405,7 +439,7 @@ describe('Wallet', () => { it('should send EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas` same as provided `gasPrice`', async () => { const tx = await wallet.sendTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, gasPrice: 3_500_000_000n, }); @@ -417,7 +451,7 @@ describe('Wallet', () => { it('should send legacy transaction when `type = 0`', async () => { const tx = await wallet.sendTransaction({ type: 0, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); const result = await tx.wait(); @@ -428,8 +462,8 @@ describe('Wallet', () => { describe('#fromMnemonic()', () => { it('should return a `Wallet` with the `provider` as L1 provider and a private key that is built from the `mnemonic` passphrase', async () => { - const wallet = Wallet.fromMnemonic(MNEMONIC, ethProvider); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + const wallet = Wallet.fromMnemonic(MNEMONIC1, ethProvider); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(wallet.providerL1).to.be.equal(ethProvider); }); }); @@ -440,7 +474,7 @@ describe('Wallet', () => { fs.readFileSync('tests/files/wallet.json', 'utf8'), 'password' ); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); }).timeout(5_000); }); @@ -450,7 +484,7 @@ describe('Wallet', () => { fs.readFileSync('tests/files/wallet.json', 'utf8'), 'password' ); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); }).timeout(5_000); }); @@ -463,300 +497,684 @@ describe('Wallet', () => { }); describe('#getDepositTx()', () => { - it('should return an ETH deposit transaction', async () => { - const tx = { - contractAddress: ADDRESS, - calldata: '0x', - l2Value: 7_000_000, - l2GasLimit: '0x8cbaa', - token: '0x0000000000000000000000000000000000000000', - to: ADDRESS, - amount: 7_000_000, - refundRecipient: ADDRESS, - operatorTip: 0, - overrides: { - from: ADDRESS, - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - value: 288_213_007_000_000n, - }, - gasPerPubdataByte: 800, - }; - const result = await wallet.getDepositTx({ - token: utils.ETH_ADDRESS, - to: await wallet.getAddress(), - amount: 7_000_000, - refundRecipient: await wallet.getAddress(), + if (IS_ETH_BASED) { + it('should return ETH deposit transaction', async () => { + const tx = { + contractAddress: ADDRESS1, + calldata: '0x', + l2Value: 7_000_000, + l2GasLimit: 415_035n, + mintValue: 111_540_663_250_000n, + token: utils.ETH_ADDRESS_IN_CONTRACTS, + to: ADDRESS1, + amount: 7_000_000, + refundRecipient: ADDRESS1, + operatorTip: 0, + overrides: { + from: ADDRESS1, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 111_540_663_250_000n, + }, + gasPerPubdataByte: 800, + }; + const result = await wallet.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: 7_000_000, + refundRecipient: await wallet.getAddress(), + }); + expect(result).to.be.deepEqualExcluding(tx, [ + 'l2GasLimit', + 'mintValue', + 'overrides', + ]); + expect(result.overrides).to.be.deepEqualExcluding(tx.overrides, [ + 'value', + ]); }); - expect(result).to.be.deep.equal(tx); - }); - it('should return a deposit transaction with `tx.to == Wallet.getAddress()` when `tx.to` is not specified', async () => { - const tx = { - contractAddress: ADDRESS, - calldata: '0x', - l2Value: 7_000_000, - l2GasLimit: '0x8cbaa', - token: '0x0000000000000000000000000000000000000000', - to: ADDRESS, - amount: 7_000_000, - refundRecipient: ADDRESS, - operatorTip: 0, - overrides: { - from: ADDRESS, - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - value: 288_213_007_000_000n, - }, - gasPerPubdataByte: 800, - }; - const result = await wallet.getDepositTx({ - token: utils.ETH_ADDRESS, - amount: 7_000_000, - refundRecipient: await wallet.getAddress(), + it('should return a deposit transaction with `tx.to == Wallet.getAddress()` when `tx.to` is not specified', async () => { + const tx = { + contractAddress: ADDRESS1, + calldata: '0x', + l2Value: 7_000_000, + l2GasLimit: 415_035n, + mintValue: 111_540_663_250_000n, + token: utils.ETH_ADDRESS_IN_CONTRACTS, + to: ADDRESS1, + amount: 7_000_000, + refundRecipient: ADDRESS1, + operatorTip: 0, + overrides: { + from: ADDRESS1, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 111_540_663_250_000n, + }, + gasPerPubdataByte: 800, + }; + const result = await wallet.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + amount: 7_000_000, + refundRecipient: await wallet.getAddress(), + }); + expect(result).to.be.deepEqualExcluding(tx, [ + 'l2GasLimit', + 'mintValue', + 'overrides', + ]); + expect(result.overrides).to.be.deepEqualExcluding(tx.overrides, [ + 'value', + ]); }); - expect(result).to.be.deep.equal(tx); - }); - it('should return a DAI deposit transaction', async () => { - const tx = { - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - value: 288_992_000_000_000n, - from: ADDRESS, - to: await (await wallet.getL1BridgeContracts()).erc20.getAddress(), - }; - const result = await wallet.getDepositTx({ - token: DAI_L1, - to: await wallet.getAddress(), - amount: 5, - refundRecipient: await wallet.getAddress(), + it('should return DAI deposit transaction', async () => { + const transaction = { + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 105_100_275_000_000n, + from: ADDRESS1, + to: await provider.getBridgehubContractAddress(), + }; + const tx = await wallet.getDepositTx({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: 5, + refundRecipient: await wallet.getAddress(), + }); + tx.to = tx.to.toLowerCase(); + expect(tx).to.be.deepEqualExcluding(transaction, ['data']); + }); + } else { + it('should return ETH deposit transaction', async () => { + const tx = { + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + value: 7_000_000n, + data: '0x24fd57fb0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010e0000000000000000000000000000000000000000000000000000bf1aaa17ee7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062e3d000000000000000000000000000000000000000000000000000000000000032000000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049000000000000000000000000842deab39809094bf5e4b77a7f97ae308adc5e5500000000000000000000000000000000000000000000000000000000006acfc0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049', + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + }; + const result = await wallet.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: 7_000_000, + refundRecipient: await wallet.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, ['data']); }); - expect(result).to.be.deepEqualExcluding(tx, ['data']); - }); - }); - describe('#estimateGasDeposit()', () => { - it('should return a gas estimation for the ETH deposit transaction', async () => { - const result = await wallet.estimateGasDeposit({ - token: utils.ETH_ADDRESS, - to: await wallet.getAddress(), - amount: 5, - refundRecipient: await wallet.getAddress(), + it('should return a deposit transaction with `tx.to == Wallet.getAddress()` when `tx.to` is not specified', async () => { + const tx = { + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + value: 7_000_000n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1000_000_000n, + }; + const result = await wallet.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + amount: 7_000_000, + refundRecipient: await wallet.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, ['data']); }); - expect(result).to.be.equal(132_711n); - }); - it('should return a gas estimation for the DAI deposit transaction', async () => { - const result = await wallet.estimateGasDeposit({ - token: DAI_L1, - to: await wallet.getAddress(), - amount: 5, - refundRecipient: await wallet.getAddress(), + it('should return DAI deposit transaction', async () => { + const tx = { + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 0n, + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + }; + const result = await wallet.getDepositTx({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: 5, + refundRecipient: await wallet.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, ['data']); }); - expect(result).to.be.equal(253_418n); - }); + } }); - describe('#deposit()', () => { - it('should deposit ETH to the L2 network', async () => { - const amount = 7_000_000_000n; - const l2BalanceBeforeDeposit = await wallet.getBalance(); - const l1BalanceBeforeDeposit = await wallet.getBalanceL1(); - const tx = await wallet.deposit({ - token: utils.ETH_ADDRESS, - to: await wallet.getAddress(), - amount: amount, - refundRecipient: await wallet.getAddress(), + describe('#estimateGasDeposit()', () => { + if (IS_ETH_BASED) { + it('should return gas estimation for ETH deposit transaction', async () => { + const result = await wallet.estimateGasDeposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: 5, + refundRecipient: await wallet.getAddress(), + }); + expectBigNumberCloseTo(result, 225_078n, tolerancePercentage); }); - const result = await tx.wait(); - const l2BalanceAfterDeposit = await wallet.getBalance(); - const l1BalanceAfterDeposit = await wallet.getBalanceL1(); - expect(result).not.to.be.null; - expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be - .true; - expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be - .true; - }).timeout(20_000); - it('should deposit DAI to the L2 network', async () => { - const amount = 5n; - const l2DAI = await provider.l2TokenAddress(DAI_L1); - const l2BalanceBeforeDeposit = await wallet.getBalance(l2DAI); - const l1BalanceBeforeDeposit = await wallet.getBalanceL1(DAI_L1); - const tx = await wallet.deposit({ - token: DAI_L1, - to: await wallet.getAddress(), - amount: amount, - approveERC20: true, - refundRecipient: await wallet.getAddress(), - }); - const result = await tx.wait(); - const l2BalanceAfterDeposit = await wallet.getBalance(l2DAI); - const l1BalanceAfterDeposit = await wallet.getBalanceL1(DAI_L1); - expect(result).not.to.be.null; - expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit === amount).to.be - .true; - expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit === amount).to.be - .true; - }).timeout(20_000); - - it('should deposit DAI to the L2 network with approve transaction for allowance', async () => { - const amount = 7n; - const l2DAI = await provider.l2TokenAddress(DAI_L1); - const l2BalanceBeforeDeposit = await wallet.getBalance(l2DAI); - const l1BalanceBeforeDeposit = await wallet.getBalanceL1(DAI_L1); - const tx = await wallet.deposit({ - token: DAI_L1, - to: await wallet.getAddress(), - amount: amount, - approveERC20: true, - refundRecipient: await wallet.getAddress(), - }); - const result = await tx.wait(); - await tx.waitFinalize(); - const l2BalanceAfterDeposit = await wallet.getBalance(l2DAI); - const l1BalanceAfterDeposit = await wallet.getBalanceL1(DAI_L1); - expect(result).not.to.be.null; - expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit === amount).to.be - .true; - expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit === amount).to.be - .true; - }).timeout(30_000); - - it('should deposit USDC using custom bridge', async () => { - const amount = 7n; - const l2USDC = CustomBridge.l2Token; - const l1USDC = CustomBridge.l1Token; - const l2BalanceBeforeDeposit = await wallet.getBalance(l2USDC); - const l1BalanceBeforeDeposit = await wallet.getBalanceL1(l1USDC); - const tx = await wallet.deposit({ - token: l1USDC, - bridgeAddress: CustomBridge.l1Bridge, - to: await wallet.getAddress(), - amount: amount, - approveERC20: true, - refundRecipient: await wallet.getAddress(), + it('should return gas estimation for DAI deposit transaction', async () => { + const result = await wallet.estimateGasDeposit({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: 5, + refundRecipient: await wallet.getAddress(), + }); + expectBigNumberCloseTo(result, 338_196n, tolerancePercentage); }); - const result = await tx.wait(); - await tx.waitFinalize(); - const l2BalanceAfterDeposit = await wallet.getBalance(l2USDC); - const l1BalanceAfterDeposit = await wallet.getBalanceL1(l1USDC); - expect(result).not.to.be.null; - expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit === amount).to.be - .true; - expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit === amount).to.be - .true; - }).timeout(30_000); - }); + } else { + it('should throw an error for insufficient allowance when estimating gas for ETH deposit transaction', async () => { + try { + await wallet.estimateGasDeposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: 5, + refundRecipient: await wallet.getAddress(), + }); + } catch (e: any) { + expect(e.reason).to.include('ERC20: insufficient allowance'); + } + }).timeout(10_000); + + it('should return gas estimation for ETH deposit transaction', async () => { + const token = utils.LEGACY_ETH_ADDRESS; + const amount = 5; + const approveParams = await wallet.getDepositAllowanceParams( + token, + amount + ); - describe('#claimFailedDeposit()', () => { - // it("should claim failed deposit", async () => { - // const response = await wallet.deposit({ - // token: utils.ETH_ADDRESS, - // to: await wallet.getAddress(), - // amount: 7_000_000_000, - // refundRecipient: await wallet.getAddress(), - // gasPerPubdataByte: 500 // make it fail because of low gas - // }); - // - // const tx = await response.waitFinalize(); // fails, sames goes with response.wait() - // const result = await wallet.claimFailedDeposit(tx.hash); - // - // }).timeout(30_000); - - it('should throw an error when trying to claim successful deposit', async () => { - const response = await wallet.deposit({ - token: utils.ETH_ADDRESS, - to: await wallet.getAddress(), - amount: 7_000_000_000, - refundRecipient: await wallet.getAddress(), - }); + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); - const tx = await response.waitFinalize(); - try { - await wallet.claimFailedDeposit(tx.hash); - } catch (e) { - expect((e as Error).message).to.be.equal( - 'Cannot claim successful deposit!' + const result = await wallet.estimateGasDeposit({ + token: token, + to: await wallet.getAddress(), + amount: amount, + refundRecipient: await wallet.getAddress(), + }); + expect(result > 0).to.be.true; + }).timeout(10_000); + + it('should return gas estimation for base token deposit transaction', async () => { + const token = await wallet.getBaseToken(); + const amount = 5; + const approveParams = await wallet.getDepositAllowanceParams( + token, + amount ); - } - }).timeout(30_000); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await wallet.estimateGasDeposit({ + token: token, + to: await wallet.getAddress(), + amount: amount, + refundRecipient: await wallet.getAddress(), + }); + expect(result > 0).to.be.true; + }).timeout(10_000); + + it('should return gas estimation for DAI deposit transaction', async () => { + const token = DAI_L1; + const amount = 5; + const approveParams = await wallet.getDepositAllowanceParams( + token, + amount + ); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + await ( + await wallet.approveERC20( + approveParams[1].token, + approveParams[1].allowance + ) + ).wait(); + + const result = await wallet.estimateGasDeposit({ + token: token, + to: await wallet.getAddress(), + amount: amount, + refundRecipient: await wallet.getAddress(), + }); + expectBigNumberCloseTo(result, 361_501n, tolerancePercentage); + }).timeout(10_000); + } + }); + + describe('#deposit()', () => { + if (IS_ETH_BASED) { + it('should deposit ETH to L2 network', async () => { + const amount = 7_000_000_000; + const l2BalanceBeforeDeposit = await wallet.getBalance(); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(); + const tx = await wallet.deposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: amount, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + const l2BalanceAfterDeposit = await wallet.getBalance(); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be + .true; + }).timeout(10_000); + + it('should deposit DAI to L2 network', async () => { + const amount = 5; + const l2DAI = await provider.l2TokenAddress(DAI_L1); + const l2BalanceBeforeDeposit = await wallet.getBalance(l2DAI); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(DAI_L1); + const tx = await wallet.deposit({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: amount, + approveERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + const l2BalanceAfterDeposit = await wallet.getBalance(l2DAI); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(DAI_L1); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be + .true; + }).timeout(10_000); + + it('should deposit DAI to the L2 network with approve transaction for allowance', async () => { + const amount = 7; + const l2DAI = await provider.l2TokenAddress(DAI_L1); + const l2BalanceBeforeDeposit = await wallet.getBalance(l2DAI); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(DAI_L1); + const tx = await wallet.deposit({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: amount, + approveERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + await tx.waitFinalize(); + const l2BalanceAfterDeposit = await wallet.getBalance(l2DAI); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(DAI_L1); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be + .true; + }).timeout(30_000); + } else { + it('should deposit ETH to L2 network', async () => { + const amount = 7_000_000_000; + const l2BalanceBeforeDeposit = await wallet.getBalance(); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(); + const tx = await wallet.deposit({ + token: utils.ETH_ADDRESS, + to: await wallet.getAddress(), + amount: amount, + approveBaseERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + const l2BalanceAfterDeposit = await wallet.getBalance(); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be + .true; + }).timeout(20_000); + + it('should deposit base token to L2 network', async () => { + const amount = 5; + const baseTokenL1 = await wallet.getBaseToken(); + const l2BalanceBeforeDeposit = await wallet.getBalance(); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(baseTokenL1); + const tx = await wallet.deposit({ + token: baseTokenL1, + to: await wallet.getAddress(), + amount: amount, + approveERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + const l2BalanceAfterDeposit = await wallet.getBalance(); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(baseTokenL1); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= 0).to.be.true; + }).timeout(20_000); + + it('should deposit DAI to L2 network', async () => { + const amount = 5; + const l2DAI = await provider.l2TokenAddress(DAI_L1); + const l2BalanceBeforeDeposit = await wallet.getBalance(l2DAI); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(DAI_L1); + const tx = await wallet.deposit({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: amount, + approveERC20: true, + approveBaseERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + const l2BalanceAfterDeposit = await wallet.getBalance(l2DAI); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(DAI_L1); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be + .true; + }).timeout(20_000); + } + }); + + describe('#claimFailedDeposit()', () => { + if (IS_ETH_BASED) { + it('should claim failed deposit', async () => { + const response = await wallet.deposit({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: 5, + approveERC20: true, + refundRecipient: await wallet.getAddress(), + l2GasLimit: 300_000, // make it fail because of low gas + }); + try { + await response.waitFinalize(); + } catch (error) { + await utils.sleep(10_000); + const tx = await wallet.claimFailedDeposit( + (error as any).receipt.hash + ); + const result = await tx.wait(); + expect(result?.blockHash).to.be.not.null; + } + }).timeout(40_000); + + it('should throw an error when trying to claim successful deposit', async () => { + const response = await wallet.deposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: 7_000_000_000, + refundRecipient: await wallet.getAddress(), + }); + const tx = await response.waitFinalize(); + try { + await wallet.claimFailedDeposit(tx.hash); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Cannot claim successful deposit!' + ); + } + }).timeout(30_000); + } else { + it('should throw an error when trying to claim successful deposit', async () => { + const response = await wallet.deposit({ + token: await wallet.getBaseToken(), + to: await wallet.getAddress(), + amount: 5, + approveERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const tx = await response.waitFinalize(); + try { + await wallet.claimFailedDeposit(tx.hash); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Cannot claim successful deposit!' + ); + } + }).timeout(30_000); + } }); describe('#getFullRequiredDepositFee()', () => { - it('should return a fee for ETH token deposit', async () => { - const feeData = { - baseCost: 285_096_500_000_000n, - l1GasLimit: 132_711n, - l2GasLimit: '0x8b351', - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - }; - const result = await wallet.getFullRequiredDepositFee({ - token: utils.ETH_ADDRESS, - to: await wallet.getAddress(), + if (IS_ETH_BASED) { + it('should return fee for ETH token deposit', async () => { + const fee = { + baseCost: 95_595_450_000_000n, + l1GasLimit: 225_079n, + l2GasLimit: 355_704n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + }; + const result = await wallet.getFullRequiredDepositFee({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + }); + expectFeeDataCloseToExpected(result, fee, tolerancePercentage); }); - expect(result).to.be.deep.equal(feeData); - }); - it('should throw an error when there is not enough allowance to cover the deposit', async () => { - try { - await wallet.getFullRequiredDepositFee({ + it('should throw an error when there is not enough allowance to cover the deposit', async () => { + try { + await wallet.getFullRequiredDepositFee({ + token: DAI_L1, + to: await wallet.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough allowance to cover the deposit!' + ); + } + }).timeout(10_000); + + it('should return fee for DAI token deposit', async () => { + const fee = { + baseCost: 107_602_662_500_000n, + l1GasLimit: 337_820n, + l2GasLimit: 400_382n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + }; + + const tx = await wallet.approveERC20(DAI_L1, 5); + await tx.wait(); + + const result = await wallet.getFullRequiredDepositFee({ token: DAI_L1, to: await wallet.getAddress(), }); - } catch (e) { - expect((e as Error).message).to.be.equal( - 'Not enough allowance to cover the deposit!' - ); - } - }).timeout(10_000); + expectFeeDataCloseToExpected(result, fee, tolerancePercentage); + }).timeout(10_000); + + it('should throw an error when there is not enough balance for the deposit', async () => { + try { + const randomWallet = new Wallet( + ethers.Wallet.createRandom().privateKey, + provider, + ethProvider + ); + await randomWallet.getFullRequiredDepositFee({ + token: DAI_L1, + to: await wallet.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.include( + 'Not enough balance for deposit!' + ); + } + }).timeout(10_000); + } else { + it('should throw an error when there is not enough base token allowance to cover the deposit', async () => { + try { + await new Wallet( + ethers.Wallet.createRandom().privateKey, + provider, + ethProvider + ).getFullRequiredDepositFee({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough base token allowance to cover the deposit!' + ); + } + }).timeout(10_000); + + it('should return fee for ETH token deposit', async () => { + const fee = { + baseCost: 111_540_656_250_000n, + l1GasLimit: 321_051n, + l2GasLimit: 415_035n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + }; + const token = utils.LEGACY_ETH_ADDRESS; + const approveParams = await wallet.getDepositAllowanceParams(token, 1); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await wallet.getFullRequiredDepositFee({ + token: token, + to: await wallet.getAddress(), + }); - it('should return a fee for DAI token deposit', async () => { - const feeData = { - baseCost: 288_992_000_000_000n, - l1GasLimit: 253_177n, - l2GasLimit: '0x8d1c0', - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - }; + expectFeeDataCloseToExpected(result, fee, tolerancePercentage); + }).timeout(10_000); - const tx = await wallet.approveERC20(DAI_L1, 5); - await tx.wait(); + it('should return fee for base token deposit', async () => { + const token = await wallet.getBaseToken(); + const approveParams = await wallet.getDepositAllowanceParams(token, 1); - const result = await wallet.getFullRequiredDepositFee({ - token: DAI_L1, - to: await wallet.getAddress(), - }); - expect(result).to.be.deep.equal(feeData); - }).timeout(10_000); + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); - it('should throw an error when there is not enough balance for the deposit', async () => { - try { + const result = await wallet.getFullRequiredDepositFee({ + token: token, + to: await wallet.getAddress(), + }); + expect(result).not.to.be.null; + }).timeout(10_000); + + it('should return fee for DAI token deposit', async () => { + const fee = { + baseCost: 107_602_662_500_000n, + l1GasLimit: 361_124n, + l2GasLimit: 400_382n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + }; + const token = DAI_L1; + const approveParams = await wallet.getDepositAllowanceParams(token, 1); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + await ( + await wallet.approveERC20( + approveParams[1].token, + approveParams[1].allowance + ) + ).wait(); + + const result = await wallet.getFullRequiredDepositFee({ + token: token, + to: await wallet.getAddress(), + }); + expectFeeDataCloseToExpected(result, fee, tolerancePercentage); + }).timeout(10_000); + + it('should throw an error when there is not enough token allowance to cover the deposit', async () => { + const token = DAI_L1; const randomWallet = new Wallet( ethers.Wallet.createRandom().privateKey, provider, ethProvider ); - await randomWallet.getFullRequiredDepositFee({ - token: DAI_L1, - to: await wallet.getAddress(), + + // mint base token to random wallet + const baseToken = ITestnetERC20Token__factory.connect( + await wallet.getBaseToken(), + wallet._signerL1() + ); + const baseTokenMintTx = await baseToken.mint( + await randomWallet.getAddress(), + ethers.parseEther('0.5') + ); + await baseTokenMintTx.wait(); + + // transfer ETH to random wallet so that base token approval tx can be performed + const transferTx = await new ethers.Wallet( + PRIVATE_KEY1, + ethProvider + ).sendTransaction({ + to: await randomWallet.getAddress(), + value: ethers.parseEther('0.1'), }); - } catch (e) { - expect((e as Error).message).to.include( - 'Not enough balance for deposit!' + await transferTx.wait(); + + const approveParams = await randomWallet.getDepositAllowanceParams( + token, + 1 ); - } - }).timeout(10_000); + // only approve base token + await ( + await randomWallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + try { + await randomWallet.getFullRequiredDepositFee({ + token: token, + to: await wallet.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough token allowance to cover the deposit!' + ); + } + }).timeout(20_000); + } }); describe('#withdraw()', () => { it('should withdraw ETH to the L1 network', async () => { const amount = 7_000_000_000n; const l2BalanceBeforeWithdrawal = await wallet.getBalance(); + const token = IS_ETH_BASED + ? utils.ETH_ADDRESS_IN_CONTRACTS + : await wallet.l2TokenAddress(utils.ETH_ADDRESS_IN_CONTRACTS); const withdrawTx = await wallet.withdraw({ - token: utils.ETH_ADDRESS, + token: token, to: await wallet.getAddress(), amount: amount, }); @@ -782,19 +1200,19 @@ describe('Wallet', () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await wallet.getBalance(); const l2ApprovalTokenBalanceBeforeWithdrawal = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); const withdrawTx = await wallet.withdraw({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, to: await wallet.getAddress(), amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -812,11 +1230,11 @@ describe('Wallet', () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await wallet.getBalance(); const l2ApprovalTokenBalanceAfterWithdrawal = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0n @@ -877,12 +1295,12 @@ describe('Wallet', () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await wallet.getBalance(l2DAI); const l1BalanceBeforeWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceBeforeWithdrawal = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); const withdrawTx = await wallet.withdraw({ token: l2DAI, @@ -890,7 +1308,7 @@ describe('Wallet', () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -908,12 +1326,12 @@ describe('Wallet', () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await wallet.getBalance(l2DAI); const l1BalanceAfterWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceAfterWithdrawal = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0n @@ -935,95 +1353,141 @@ describe('Wallet', () => { amount ); }).timeout(25_000); - - it('should withdraw USDC to the L1 network using custom bridge', async () => { - const amount = 5n; - const l2USDC = CustomBridge.l2Token; - const l1USDC = CustomBridge.l1Token; - const l2BalanceBeforeWithdrawal = await wallet.getBalance(l2USDC); - const l1BalanceBeforeWithdrawal = await wallet.getBalanceL1(l1USDC); - - const withdrawTx = await wallet.withdraw({ - token: l2USDC, - bridgeAddress: CustomBridge.l2Bridge, - to: await wallet.getAddress(), - amount: amount, - }); - await withdrawTx.waitFinalize(); - expect(await wallet.isWithdrawalFinalized(withdrawTx.hash)).to.be.false; - - const finalizeWithdrawTx = await wallet.finalizeWithdrawal( - withdrawTx.hash - ); - const result = await finalizeWithdrawTx.wait(); - const l2BalanceAfterWithdrawal = await wallet.getBalance(l2USDC); - const l1BalanceAfterWithdrawal = await wallet.getBalanceL1(l1USDC); - - expect(result).not.to.be.null; - expect(l2BalanceBeforeWithdrawal - l2BalanceAfterWithdrawal).to.be.equal( - amount - ); - expect(l1BalanceAfterWithdrawal - l1BalanceBeforeWithdrawal).to.be.equal( - amount - ); - }).timeout(25_000); }); describe('#getRequestExecuteTx()', () => { - it('should return a request execute transaction', async () => { - const result = await wallet.getRequestExecuteTx({ - contractAddress: await provider.getMainContractAddress(), - calldata: '0x', - l2Value: 7_000_000_000, + const amount = 7_000_000_000; + if (IS_ETH_BASED) { + it('should return request execute transaction', async () => { + const result = await wallet.getRequestExecuteTx({ + contractAddress: await provider.getBridgehubContractAddress(), + calldata: '0x', + l2Value: amount, + }); + expect(result).not.to.be.null; }); - expect(result).not.to.be.null; - }); + } else { + it('should return request execute transaction', async () => { + const result = await wallet.getRequestExecuteTx({ + contractAddress: await wallet.getAddress(), + calldata: '0x', + l2Value: amount, + overrides: {nonce: 0}, + }); + expect(result).not.to.be.null; + }); + } }); describe('#estimateGasRequestExecute()', () => { - it('should return a gas estimation for the request execute transaction', async () => { - const result = await wallet.estimateGasRequestExecute({ - contractAddress: await provider.getMainContractAddress(), - calldata: '0x', - l2Value: 7_000_000_000, + if (IS_ETH_BASED) { + it('should return gas estimation for request execute transaction', async () => { + const result = await wallet.estimateGasRequestExecute({ + contractAddress: await provider.getBridgehubContractAddress(), + calldata: '0x', + l2Value: 7_000_000_000, + }); + expect(result > 0).to.be.true; }); - expect(result > 0n).to.be.true; - }); + } else { + it('should return gas estimation for request execute transaction', async () => { + const tx = { + contractAddress: await wallet.getAddress(), + calldata: '0x', + l2Value: 7_000_000_000, + overrides: {value: 0}, + }; + + const approveParams = await wallet.getRequestExecuteAllowanceParams(tx); + await ( + await wallet.approveERC20( + approveParams.token, + approveParams.allowance + ) + ).wait(); + + const result = await wallet.estimateGasRequestExecute(tx); + expect(result > 0).to.be.true; + }).timeout(10_000); + } }); describe('#requestExecute()', () => { - it('should request transaction execution on the L2 network', async () => { - const amount = 7_000_000_000n; - const l2BalanceBeforeExecution = await wallet.getBalance(); - const l1BalanceBeforeExecution = await wallet.getBalanceL1(); - const tx = await wallet.requestExecute({ - contractAddress: await provider.getMainContractAddress(), - calldata: '0x', - l2Value: amount, - l2GasLimit: 900_000, - }); - const result = await tx.wait(); - const l2BalanceAfterExecution = await wallet.getBalance(); - const l1BalanceAfterExecution = await wallet.getBalanceL1(); - expect(result).not.to.be.null; - expect(l2BalanceAfterExecution - l2BalanceBeforeExecution >= amount).to.be - .true; - expect(l1BalanceBeforeExecution - l1BalanceAfterExecution >= amount).to.be - .true; - }).timeout(10_000); + if (IS_ETH_BASED) { + it('should request transaction execution on L2 network', async () => { + const amount = 7_000_000_000; + const l2BalanceBeforeExecution = await wallet.getBalance(); + const l1BalanceBeforeExecution = await wallet.getBalanceL1(); + const tx = await wallet.requestExecute({ + contractAddress: await provider.getBridgehubContractAddress(), + calldata: '0x', + l2Value: amount, + l2GasLimit: 900_000, + }); + const result = await tx.wait(); + const l2BalanceAfterExecution = await wallet.getBalance(); + const l1BalanceAfterExecution = await wallet.getBalanceL1(); + expect(result).not.to.be.null; + expect(l2BalanceAfterExecution - l2BalanceBeforeExecution >= amount).to + .be.true; + expect(l1BalanceBeforeExecution - l1BalanceAfterExecution >= amount).to + .be.true; + }).timeout(10_000); + } else { + it('should request transaction execution on L2 network', async () => { + const amount = 7_000_000_000; + const request = { + contractAddress: await wallet.getAddress(), + calldata: '0x', + l2Value: amount, + l2GasLimit: 1_319_957n, + operatorTip: 0, + gasPerPubdataByte: 800, + refundRecipient: await wallet.getAddress(), + overrides: { + maxFeePerGas: 1_000_000_010n, + maxPriorityFeePerGas: 1_000_000_000n, + gasLimit: 238_654n, + value: 0, + }, + }; + + const approveParams = + await wallet.getRequestExecuteAllowanceParams(request); + await ( + await wallet.approveERC20( + approveParams.token, + approveParams.allowance + ) + ).wait(); + + const l2BalanceBeforeExecution = await wallet.getBalance(); + const l1BalanceBeforeExecution = await wallet.getBalanceL1(); + + const tx = await wallet.requestExecute(request); + const result = await tx.wait(); + const l2BalanceAfterExecution = await wallet.getBalance(); + const l1BalanceAfterExecution = await wallet.getBalanceL1(); + expect(result).not.to.be.null; + expect(l2BalanceAfterExecution - l2BalanceBeforeExecution >= amount).to + .be.true; + expect(l1BalanceBeforeExecution - l1BalanceAfterExecution >= amount).to + .be.true; + }).timeout(10_000); + } }); describe('#transfer()', () => { it('should transfer ETH', async () => { const amount = 7_000_000_000n; - const balanceBeforeTransfer = await provider.getBalance(RECEIVER); + const balanceBeforeTransfer = await provider.getBalance(ADDRESS2); const tx = await wallet.transfer({ - token: utils.ETH_ADDRESS, - to: RECEIVER, + token: utils.LEGACY_ETH_ADDRESS, + to: ADDRESS2, amount: amount, }); const result = await tx.wait(); - const balanceAfterTransfer = await provider.getBalance(RECEIVER); + const balanceAfterTransfer = await provider.getBalance(ADDRESS2); expect(result).not.to.be.null; expect(balanceAfterTransfer - balanceBeforeTransfer).to.be.equal(amount); }).timeout(25_000); @@ -1037,20 +1501,20 @@ describe('Wallet', () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await wallet.getBalance(); const senderApprovalTokenBalanceBeforeTransfer = - await wallet.getBalance(TOKEN); - const receiverBalanceBeforeTransfer = await provider.getBalance(RECEIVER); + await wallet.getBalance(APPROVAL_TOKEN); + const receiverBalanceBeforeTransfer = await provider.getBalance(ADDRESS2); const tx = await wallet.transfer({ - token: utils.ETH_ADDRESS, - to: RECEIVER, + token: utils.LEGACY_ETH_ADDRESS, + to: ADDRESS2, amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -1062,12 +1526,12 @@ describe('Wallet', () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await wallet.getBalance(); const senderApprovalTokenBalanceAfterTransfer = - await wallet.getBalance(TOKEN); - const receiverBalanceAfterTransfer = await provider.getBalance(RECEIVER); + await wallet.getBalance(APPROVAL_TOKEN); + const receiverBalanceAfterTransfer = await provider.getBalance(ADDRESS2); expect( paymasterBalanceBeforeTransfer - paymasterBalanceAfterTransfer >= 0n @@ -1094,18 +1558,18 @@ describe('Wallet', () => { const amount = 5n; const l2DAI = await provider.l2TokenAddress(DAI_L1); const balanceBeforeTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); const tx = await wallet.transfer({ token: l2DAI, - to: RECEIVER, + to: ADDRESS2, amount: amount, }); const result = await tx.wait(); const balanceAfterTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); @@ -1123,24 +1587,24 @@ describe('Wallet', () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await wallet.getBalance(l2DAI); const senderApprovalTokenBalanceBeforeTransfer = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); const receiverBalanceBeforeTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); const tx = await wallet.transfer({ token: l2DAI, - to: RECEIVER, + to: ADDRESS2, amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -1152,13 +1616,13 @@ describe('Wallet', () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await wallet.getBalance(l2DAI); const senderApprovalTokenBalanceAfterTransfer = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); const receiverBalanceAfterTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); @@ -1183,13 +1647,31 @@ describe('Wallet', () => { receiverBalanceAfterTransfer - receiverBalanceBeforeTransfer ).to.be.equal(amount); }).timeout(25_000); + + if (!IS_ETH_BASED) { + it('should transfer base token', async () => { + const amount = 7_000_000_000n; + const balanceBeforeTransfer = await provider.getBalance(ADDRESS2); + const tx = await wallet.transfer({ + token: await wallet.getBaseToken(), + to: ADDRESS2, + amount: amount, + }); + const result = await tx.wait(); + const balanceAfterTransfer = await provider.getBalance(ADDRESS2); + expect(result).not.to.be.null; + expect(balanceAfterTransfer - balanceBeforeTransfer).to.be.equal( + amount + ); + }).timeout(25_000); + } }); describe('#signTransaction()', () => { it('should return a signed type EIP1559 transaction', async () => { const result = await wallet.signTransaction({ type: 2, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000n, }); expect(result).not.to.be.null; @@ -1198,7 +1680,7 @@ describe('Wallet', () => { it('should return a signed EIP712 transaction', async () => { const result = await wallet.signTransaction({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, + to: ADDRESS2, value: ethers.parseEther('1'), }); expect(result).not.to.be.null; @@ -1208,8 +1690,8 @@ describe('Wallet', () => { try { await wallet.signTransaction({ type: utils.EIP712_TX_TYPE, - from: RECEIVER, - to: RECEIVER, + from: ADDRESS2, + to: ADDRESS2, value: 7_000_000_000, }); } catch (e) { diff --git a/tests/setup.ts b/tests/setup.ts index d7e09806..65523771 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -7,17 +7,10 @@ import { utils, } from '../src'; import {ethers, Typed} from 'ethers'; -import {IL1Bridge} from '../src/typechain'; -import fs from 'fs'; +import {ITestnetERC20Token__factory} from '../typechain'; -import TokensL1 from './files/tokens.json'; import Token from './files/Token.json'; import Paymaster from './files/Paymaster.json'; -import TokenL2Bridged from './files/TokenL2Bridged.json'; -import TokenL1 from './files/TokenL1.json'; -import CustomBridgeL1 from './files/CustomBridgeL1.json'; -import CustomBridgeL2 from './files/CustomBridgeL2.json'; -import DiamondProxy from './files/diamondProxy.json'; const PRIVATE_KEY = '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; @@ -27,6 +20,8 @@ const ethProvider = ethers.getDefaultProvider('http://127.0.0.1:8545'); const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); +const DAI_L1 = '0x70a0F165d6f8054d0d0CF8dFd4DD2005f0AF6B55'; + const SALT = '0x293328ad84b118194c65a0dc0defdb6483740d3163fd99b260907e15f2e2f642'; const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; // deployed by using create2 and SALT @@ -87,94 +82,107 @@ async function deployPaymasterAndToken(): Promise<{ return {token: tokenAddress, paymaster: paymasterAddress}; } -// Creates token on L2 by depositing -async function createTokenL2(l1TokenAddress: string): Promise { +/* +Mints tokens on L1 in case L2 is non-ETH based chain. +It mints based token, provided alternative tokens (different from base token) and wETH. +*/ +async function mintTokensOnL1(alternativeToken: string) { + const bridgehub = await wallet.getBridgehubContract(); + const chainId = (await provider.getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + + if (baseTokenAddress !== utils.ETH_ADDRESS_IN_CONTRACTS) { + const baseToken = ITestnetERC20Token__factory.connect( + baseTokenAddress, + wallet._signerL1() + ); + const baseTokenMintTx = await baseToken.mint( + await wallet.getAddress(), + ethers.parseEther('20000') + ); + await baseTokenMintTx.wait(); + } + + const altToken = ITestnetERC20Token__factory.connect( + alternativeToken, + wallet._signerL1() + ); + const altTokenMintTx = await altToken.mint( + await wallet.getAddress(), + ethers.parseEther('20000') + ); + await altTokenMintTx.wait(); + console.log('Minting tokens on L1 finished'); +} + +/* +Send base token to L2 in case L2 in non-ETH base chain. +*/ +async function sendTokenToL2(l1TokenAddress: string) { const priorityOpResponse = await wallet.deposit({ token: l1TokenAddress, to: await wallet.getAddress(), - amount: 100, + amount: ethers.parseEther('10000'), approveERC20: true, + approveBaseERC20: true, refundRecipient: await wallet.getAddress(), }); - await priorityOpResponse.waitFinalize(); - return await wallet.l2TokenAddress(l1TokenAddress); + const receipt = await priorityOpResponse.waitFinalize(); + console.log(`Send funds tx: ${receipt.hash}`); } -async function deployCustomBridges() { - // deploy L2 token - const l2TokenFactory = new ContractFactory( - TokenL2Bridged.abi, - TokenL2Bridged.bytecode, - wallet - ); - const l2Token = (await l2TokenFactory.deploy('USDC', 'USDC', 18)) as Contract; - await l2Token.waitForDeployment(); +async function main() { + const baseToken = await wallet.getBaseToken(); + console.log(`Wallet address: ${await wallet.getAddress()}`); + console.log(`Base token L1: ${baseToken}`); - // deploy L1 token - const l1TokenFactory = new ethers.ContractFactory( - TokenL1.abi, - TokenL1.bytecode, - wallet._signerL1() + console.log( + `L1 base token balance before: ${await wallet.getBalanceL1(baseToken)}` ); - const l1Token = (await l1TokenFactory.deploy('USDC', 'USDC', 18)) as Contract; - await l1Token.waitForDeployment(); + console.log(`L2 base token balance before: ${await wallet.getBalance()}`); - // mint token to L1 - const tx = (await l1Token.mint( - wallet.address, - ethers.parseEther('100') - )) as ethers.ContractTransactionResponse; - await tx.wait(); - - // deploy custom bridges - const gasPrice = (await ethProvider.getFeeData()).gasPrice!; - const zkSync = await wallet.getMainContract(); - const requiredValueToInitializeBridge = await zkSync.l2TransactionBaseCost( - gasPrice, - 10_000_000, - utils.REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT + await mintTokensOnL1(baseToken); + await sendTokenToL2(baseToken); + + console.log( + `L1 base token balance after: ${await wallet.getBalanceL1(baseToken)}` ); - const l1BridgeFactory = new ethers.ContractFactory( - CustomBridgeL1.abi, - CustomBridgeL1.bytecode, - wallet._signerL1() + console.log(`L2 base token balance after: ${await wallet.getBalance()} \n`); + + if (baseToken !== utils.ETH_ADDRESS_IN_CONTRACTS) { + const l2EthAddress = await wallet.l2TokenAddress( + utils.ETH_ADDRESS_IN_CONTRACTS + ); + console.log(`Eth L1: ${utils.ETH_ADDRESS_IN_CONTRACTS}`); + console.log(`Eth L2: ${l2EthAddress}`); + + console.log(`L1 eth balance before: ${await wallet.getBalanceL1()}`); + console.log( + `L2 eth balance before: ${await wallet.getBalance(l2EthAddress)}` + ); + + await mintTokensOnL1(utils.ETH_ADDRESS_IN_CONTRACTS); + await sendTokenToL2(utils.ETH_ADDRESS_IN_CONTRACTS); + + console.log(`L1 eth balance after: ${await wallet.getBalanceL1()}`); + console.log( + `L2 eth balance after: ${await wallet.getBalance(l2EthAddress)}\n` + ); + } + + const l2DAIAddress = await wallet.l2TokenAddress(DAI_L1); + console.log(`DAI L1: ${DAI_L1}`); + console.log(`DAI L2: ${l2DAIAddress}`); + + console.log(`L1 DAI balance before: ${await wallet.getBalanceL1(DAI_L1)}`); + console.log( + `L2 DAI balance before: ${await wallet.getBalance(l2DAIAddress)}` ); - const l1Bridge = (await l1BridgeFactory.deploy( - [CustomBridgeL2.bytecode], - [ - await l1Token.getAddress(), - await l2Token.getAddress(), - DiamondProxy.address, - ], - requiredValueToInitializeBridge, - { - gasPrice, - value: requiredValueToInitializeBridge, - gasLimit: 10_000_000, - } - )) as IL1Bridge; - await l1Bridge.waitForDeployment(); - - // connect L2 token to L2 custom bridge - await l2Token.setBridge(await l1Bridge.l2Bridge()); - - return { - l1Token: await l1Token.getAddress(), - l2Token: await l2Token.getAddress(), - l1Bridge: await l1Bridge.getAddress(), - l2Bridge: await l1Bridge.l2Bridge(), - }; -} -/* -Deploy token to the L2 network through deposit transaction. -Deploy approval token and it's paymaster. -Deploy custom bridges for custom token. - */ -async function main() { - console.log('===== Depositing DAI to L2 ====='); - const l2DAI = await createTokenL2(TokensL1[0].address); - console.log(`L2 DAI address: ${l2DAI}`); + await mintTokensOnL1(DAI_L1); + await sendTokenToL2(DAI_L1); + console.log(`L1 DAI balance after: ${await wallet.getBalanceL1(DAI_L1)}`); + console.log(`L2 DAI balance after: ${await wallet.getBalance(l2DAIAddress)}`); console.log('===== Deploying token and paymaster ====='); const {token, paymaster} = await deployPaymasterAndToken(); @@ -182,21 +190,6 @@ async function main() { console.log(`Paymaster: ${paymaster}`); console.log(`Paymaster ETH balance: ${await provider.getBalance(paymaster)}`); console.log(`Wallet Crown balance: ${await wallet.getBalance(token)}`); - - console.log('===== Deploying custom bridges ====='); - const customAddresses = await deployCustomBridges(); - const {l1Token, l2Token, l1Bridge, l2Bridge} = customAddresses; - console.log(`L1 USDC address: ${l1Token}`); - console.log(`L2 USDC address: ${l2Token}`); - console.log(`L1 custom bridge address: ${l1Bridge}`); - console.log(`L2 custom bridge address: ${l2Bridge}`); - console.log(`L1 USDC balance: ${await wallet.getBalanceL1(l1Token)}`); - console.log(`L2 USDC balance: ${await wallet.getBalance(l2Token)}`); - - fs.writeFileSync( - 'tests/files/customBridge.json', - utils.toJSON(customAddresses) - ); } main() diff --git a/tests/unit/signer.test.ts b/tests/unit/signer.test.ts index e925984f..c7350849 100644 --- a/tests/unit/signer.test.ts +++ b/tests/unit/signer.test.ts @@ -2,19 +2,17 @@ import * as chai from 'chai'; import '../custom-matchers'; import {utils, EIP712Signer} from '../../src'; import {ethers} from 'ethers'; +import {ADDRESS1, ADDRESS2} from '../utils'; const {expect} = chai; describe('EIP712Signer', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - describe('#getSignInput()', () => { it('should return a populated transaction', async () => { const tx = { txType: utils.EIP712_TX_TYPE, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, gasLimit: 21_000n, gasPerPubdataByteLimit: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, maxFeePerGas: 250_000_000n, @@ -29,9 +27,9 @@ describe('EIP712Signer', () => { const result = EIP712Signer.getSignInput({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, - from: ADDRESS, + from: ADDRESS1, nonce: 0, chainId: 270n, gasPrice: 250_000_000n, @@ -44,8 +42,8 @@ describe('EIP712Signer', () => { it('should return a populated transaction with default values', async () => { const tx = { txType: utils.EIP712_TX_TYPE, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, gasLimit: 0n, gasPerPubdataByteLimit: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, maxFeePerGas: 0n, @@ -60,8 +58,8 @@ describe('EIP712Signer', () => { const result = EIP712Signer.getSignInput({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, }); expect(result).to.be.deep.equal(tx); }); diff --git a/tests/unit/smart-account.test.ts b/tests/unit/smart-account.test.ts index c83cd5b1..7fbdbf7f 100644 --- a/tests/unit/smart-account.test.ts +++ b/tests/unit/smart-account.test.ts @@ -9,26 +9,22 @@ import { signPayloadWithMultipleECDSA, } from '../../src/smart-account-utils'; import {TypedDataEncoder, hashMessage} from 'ethers'; +import {ADDRESS1, PRIVATE_KEY1, ADDRESS2} from '../utils'; const {expect} = chai; describe('signPayloadWithECDSA()', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - it('should return signature by signing EIP712 transaction hash', async () => { const tx: TransactionRequest = { chainId: 270, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 7_000_000_000, }; const txHash = EIP712Signer.getSignedDigest(tx); - const result = await signPayloadWithECDSA(txHash, PRIVATE_KEY); + const result = await signPayloadWithECDSA(txHash, PRIVATE_KEY1); expect(result).to.be.equal( '0x89905d36a3cdde117445d6c58627061a53f09cf0535d73719d82d4d96fe332541167e2e3d38ce3cb2751a0203eff2a71f55ad45dc91623587f5480ec1883281b1b' ); @@ -38,7 +34,7 @@ describe('signPayloadWithECDSA()', () => { const message = 'Hello World!'; const messageHash = hashMessage(message); - const result = await signPayloadWithECDSA(messageHash, PRIVATE_KEY); + const result = await signPayloadWithECDSA(messageHash, PRIVATE_KEY1); expect(result).to.be.equal( '0x7c15eb760c394b0ca49496e71d841378d8bfd4f9fb67e930eb5531485329ab7c67068d1f8ef4b480ec327214ee6ed203687e3fbe74b92367b259281e340d16fd1c' ); @@ -55,7 +51,7 @@ describe('signPayloadWithECDSA()', () => { }, {name: 'John', age: 30} ); - const result = await signPayloadWithECDSA(typedDataHash, PRIVATE_KEY); + const result = await signPayloadWithECDSA(typedDataHash, PRIVATE_KEY1); expect(result).to.be.equal( '0xbcaf0673c0c2b0e120165d207d42281d0c6e85f0a7f6b8044b0578a91cf5bda66b4aeb62aca4ae17012a38d71c9943e27285792fa7d788d848f849e3ea2e614b1b' ); @@ -124,11 +120,6 @@ describe('signPayloadWithMultipleECDSA()', () => { }); describe('populateTransaction()', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); it('should populate `tx.from` to address derived from private key if it not set', async () => { @@ -138,8 +129,8 @@ describe('populateTransaction()', () => { value: 7_000_000_000n, type: 113, data: '0x', - gasPrice: 250_000_000n, - gasLimit: 154_379n, + gasPrice: 100_000_000n, + gasLimit: 156_726n, customData: { gasPerPubdata: 50_000, factoryDeps: [], @@ -150,10 +141,10 @@ describe('populateTransaction()', () => { const result = await populateTransactionECDSA( { chainId: 270, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000, }, - PRIVATE_KEY, + PRIVATE_KEY1, provider ); expect(result).to.be.deepEqualExcluding(tx, ['nonce']); @@ -162,13 +153,13 @@ describe('populateTransaction()', () => { it('should throw an error when provider is not set', async () => { const tx: TransactionRequest = { chainId: 270, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 7_000_000_000, }; try { - await populateTransactionECDSA(tx, PRIVATE_KEY); + await populateTransactionECDSA(tx, PRIVATE_KEY1); } catch (error) { expect((error as Error).message).to.be.equal( 'Provider is required but is not provided!' @@ -178,21 +169,16 @@ describe('populateTransaction()', () => { }); describe('populateTransactionMultisig()', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - it('should throw an error when multiple keys are not provided', async () => { const tx: TransactionRequest = { chainId: 270, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 7_000_000_000, }; try { - await populateTransactionMultisigECDSA(tx, PRIVATE_KEY); + await populateTransactionMultisigECDSA(tx, PRIVATE_KEY1); } catch (error) { expect((error as Error).message).to.be.equal( 'Multiple keys are required to build the transaction!' diff --git a/tests/unit/utils.test.ts b/tests/unit/utils.test.ts index a88aeda9..17f74760 100644 --- a/tests/unit/utils.test.ts +++ b/tests/unit/utils.test.ts @@ -1,37 +1,40 @@ import {expect} from 'chai'; import {types, utils} from '../../src'; import {ethers} from 'ethers'; +import {ADDRESS1, ADDRESS2} from '../utils'; describe('utils', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - describe('#getHashedL2ToL1Msg()', () => { it('should return a hashed L2 to L1 message', async () => { const withdrawETHMessage = '0x6c0960f936615cf349d7f6344891b1e7ca7c72883f5dc04900000000000000000000000000000000000000000000000000000001a13b8600'; const withdrawETHMessageHash = '0x521bd25904766c83fe868d6a29cbffa011afd8a1754f6c9a52b053b693e42f18'; - const result = utils.getHashedL2ToL1Msg(ADDRESS, withdrawETHMessage, 0); + const result = utils.getHashedL2ToL1Msg(ADDRESS1, withdrawETHMessage, 0); expect(result).to.be.equal(withdrawETHMessageHash); }); }); describe('#isETH()', () => { + it('should return true for legacy L1 ETH address', async () => { + const result = utils.isETH(utils.LEGACY_ETH_ADDRESS); + expect(result).to.be.true; + }); + it('should return true for L1 ETH address', async () => { - const result = utils.isETH(utils.ETH_ADDRESS); + const result = utils.isETH(utils.ETH_ADDRESS_IN_CONTRACTS); expect(result).to.be.true; }); it('should return true for L2 ETH address', async () => { - const result = utils.isETH(utils.L2_ETH_TOKEN_ADDRESS); + const result = utils.isETH(utils.L2_BASE_TOKEN_ADDRESS); expect(result).to.be.true; }); }); describe('#createAddress()', () => { it('should return a correct address', async () => { - const address = utils.createAddress(ADDRESS, 1); + const address = utils.createAddress(ADDRESS1, 1); expect(address).to.be.equal('0x4B5DF730c2e6b28E17013A1485E5d9BC41Efe021'); }); }); @@ -39,7 +42,7 @@ describe('utils', () => { describe('#create2Address()', () => { it('should return a correct address', async () => { const address = utils.create2Address( - ADDRESS, + ADDRESS1, '0x010001cb6a6e8d5f6829522f19fa9568660e0a9cd53b2e8be4deb0a679452e41', '0x01', '0x01' @@ -132,7 +135,7 @@ describe('utils', () => { try { utils.serializeEip712({ chainId: 270, - from: ADDRESS, + from: ADDRESS1, customData: { customSignature: '', }, @@ -149,7 +152,7 @@ describe('utils', () => { '0x71ea8080808080808082010e808082010e9436615cf349d7f6344891b1e7ca7c72883f5dc04982c350c080c0'; const result = utils.serializeEip712({ chainId: 270, - from: ADDRESS, + from: ADDRESS1, }); expect(result).to.be.equal(tx); }); @@ -163,8 +166,8 @@ describe('utils', () => { const result = utils.serializeEip712( { chainId: 270, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 1_000_000, }, signature @@ -236,11 +239,11 @@ describe('utils', () => { maxPriorityFeePerGas: 0n, maxFeePerGas: 0n, gasLimit: 0n, - to: RECEIVER, + to: ADDRESS2, value: 1_000_000n, data: '0x', chainId: 270n, - from: ADDRESS, + from: ADDRESS1, customData: { gasPerPubdata: 50_000n, factoryDeps: [], @@ -263,11 +266,11 @@ describe('utils', () => { maxPriorityFeePerGas: 0n, maxFeePerGas: 0n, gasLimit: 0n, - to: RECEIVER, + to: ADDRESS2, value: 0n, data: '0x', chainId: 270n, - from: ADDRESS, + from: ADDRESS1, customData: { gasPerPubdata: 50_000n, factoryDeps: [], diff --git a/tests/utils.ts b/tests/utils.ts new file mode 100644 index 00000000..0a72a7d3 --- /dev/null +++ b/tests/utils.ts @@ -0,0 +1,13 @@ +export const ADDRESS1 = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; +export const PRIVATE_KEY1 = + '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; +export const MNEMONIC1 = + 'stuff slice staff easily soup parent arm payment cotton trade scatter struggle'; +export const ADDRESS2 = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; +export const PRIVATE_KEY2 = + '0xac1e735be8536c6534bb4f17f06f6afc73b2b5ba84ac2cfb12f7461b20c0bbe3'; +export const DAI_L1 = '0x70a0F165d6f8054d0d0CF8dFd4DD2005f0AF6B55'; +export const APPROVAL_TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; // Crown token +export const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; // Crown token paymaster + +export const IS_ETH_BASED = true;