From 56cf31ceb7875e8bfa237884d0f0743199164ef8 Mon Sep 17 00:00:00 2001 From: Akash Gianchandani Date: Fri, 27 Oct 2023 15:56:43 +0530 Subject: [PATCH 1/3] feat(eth-multisig-v4): add arbeth wallet contract WIN-1013 --- contracts/coins/ArbethWalletSimple.sol | 57 ++++++++++++++++++++++++++ test/walletSimple.js | 8 ++++ 2 files changed, 65 insertions(+) create mode 100644 contracts/coins/ArbethWalletSimple.sol diff --git a/contracts/coins/ArbethWalletSimple.sol b/contracts/coins/ArbethWalletSimple.sol new file mode 100644 index 0000000..7970f64 --- /dev/null +++ b/contracts/coins/ArbethWalletSimple.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.20; +import '../Forwarder.sol'; +import '../ERC20Interface.sol'; +import '../WalletSimple.sol'; + +/** + * + * WalletSimple + * ============ + * + * Basic multi-signer wallet designed for use in a co-signing environment where 2 signatures are required to move funds. + * Typically used in a 2-of-3 signing configuration. Uses ecrecover to allow for 2 signatures in a single transaction. + * + * The first signature is created on the operation hash (see Data Formats) and passed to sendMultiSig/sendMultiSigToken + * The signer is determined by verifyMultiSig(). + * + * The second signature is created by the submitter of the transaction and determined by msg.signer. + * + * Data Formats + * ============ + * + * The signature is created with ethereumjs-util.ecsign(operationHash). + * Like the eth_sign RPC call, it packs the values as a 65-byte array of [r, s, v]. + * Unlike eth_sign, the message is not prefixed. + * + * The operationHash the result of keccak256(prefix, toAddress, value, data, expireTime). + * For ether transactions, `prefix` is "ARBETH". + * For token transaction, `prefix` is "ARBETH-ERC20" and `data` is the tokenContractAddress. + * + * + */ +contract ArbethWalletSimple is WalletSimple { + /** + * Get the network identifier that signers must sign over + * This provides protection signatures being replayed on other chains + */ + function getNetworkId() internal override pure returns (string memory) { + return 'ARBETH'; + } + + /** + * Get the network identifier that signers must sign over for token transfers + * This provides protection signatures being replayed on other chains + */ + function getTokenNetworkId() internal override pure returns (string memory) { + return 'ARBETH-ERC20'; + } + + /** + * Get the network identifier that signers must sign over for batch transfers + * This provides protection signatures being replayed on other chains + */ + function getBatchNetworkId() internal override pure returns (string memory) { + return 'ARBETH-Batch'; + } +} diff --git a/test/walletSimple.js b/test/walletSimple.js index 3e21c6d..625b200 100644 --- a/test/walletSimple.js +++ b/test/walletSimple.js @@ -29,6 +29,7 @@ const RskWalletSimple = artifacts.require('./RskWalletSimple.sol'); const EtcWalletSimple = artifacts.require('./EtcWalletSimple.sol'); const CeloWalletSimple = artifacts.require('./CeloWalletSimple.sol'); const PolygonWalletSimple = artifacts.require('./PolygonWalletSimple.sol'); +const ArbethWalletSimple = artifacts.require('./ArbethWalletSimple.sol'); const Fail = artifacts.require('./Fail.sol'); const GasGuzzler = artifacts.require('./GasGuzzler.sol'); const GasHeavy = artifacts.require('./GasHeavy.sol'); @@ -79,6 +80,13 @@ const coins = [ nativeBatchPrefix: 'POLYGON-Batch', tokenPrefix: 'POLYGON-ERC20', WalletSimple: PolygonWalletSimple + }, + { + name: 'Arbeth', + nativePrefix: 'ARBETH', + nativeBatchPrefix: 'ARBETH-Batch', + tokenPrefix: 'ARBETH-ERC20', + WalletSimple: ArbethWalletSimple } ]; From 7f50b9cc7d84aed7f1409495561f81515b84587c Mon Sep 17 00:00:00 2001 From: Akash Gianchandani Date: Fri, 27 Oct 2023 16:29:24 +0530 Subject: [PATCH 2/3] feat(eth-multisig-v4): add opeth wallet contract --- contracts/coins/OpethWalletSimple.sol | 57 +++++++++++++++++++++++++++ test/walletSimple.js | 8 ++++ 2 files changed, 65 insertions(+) create mode 100644 contracts/coins/OpethWalletSimple.sol diff --git a/contracts/coins/OpethWalletSimple.sol b/contracts/coins/OpethWalletSimple.sol new file mode 100644 index 0000000..c8f8626 --- /dev/null +++ b/contracts/coins/OpethWalletSimple.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.20; +import '../Forwarder.sol'; +import '../ERC20Interface.sol'; +import '../WalletSimple.sol'; + +/** + * + * WalletSimple + * ============ + * + * Basic multi-signer wallet designed for use in a co-signing environment where 2 signatures are required to move funds. + * Typically used in a 2-of-3 signing configuration. Uses ecrecover to allow for 2 signatures in a single transaction. + * + * The first signature is created on the operation hash (see Data Formats) and passed to sendMultiSig/sendMultiSigToken + * The signer is determined by verifyMultiSig(). + * + * The second signature is created by the submitter of the transaction and determined by msg.signer. + * + * Data Formats + * ============ + * + * The signature is created with ethereumjs-util.ecsign(operationHash). + * Like the eth_sign RPC call, it packs the values as a 65-byte array of [r, s, v]. + * Unlike eth_sign, the message is not prefixed. + * + * The operationHash the result of keccak256(prefix, toAddress, value, data, expireTime). + * For ether transactions, `prefix` is "OPETH". + * For token transaction, `prefix` is "OPETH-ERC20" and `data` is the tokenContractAddress. + * + * + */ +contract OpethWalletSimple is WalletSimple { + /** + * Get the network identifier that signers must sign over + * This provides protection signatures being replayed on other chains + */ + function getNetworkId() internal override pure returns (string memory) { + return 'OPETH'; + } + + /** + * Get the network identifier that signers must sign over for token transfers + * This provides protection signatures being replayed on other chains + */ + function getTokenNetworkId() internal override pure returns (string memory) { + return 'OPETH-ERC20'; + } + + /** + * Get the network identifier that signers must sign over for batch transfers + * This provides protection signatures being replayed on other chains + */ + function getBatchNetworkId() internal override pure returns (string memory) { + return 'OPETH-Batch'; + } +} diff --git a/test/walletSimple.js b/test/walletSimple.js index 625b200..b844b88 100644 --- a/test/walletSimple.js +++ b/test/walletSimple.js @@ -30,6 +30,7 @@ const EtcWalletSimple = artifacts.require('./EtcWalletSimple.sol'); const CeloWalletSimple = artifacts.require('./CeloWalletSimple.sol'); const PolygonWalletSimple = artifacts.require('./PolygonWalletSimple.sol'); const ArbethWalletSimple = artifacts.require('./ArbethWalletSimple.sol'); +const OpethWalletSimple = artifacts.require('./OpethWalletSimple.sol'); const Fail = artifacts.require('./Fail.sol'); const GasGuzzler = artifacts.require('./GasGuzzler.sol'); const GasHeavy = artifacts.require('./GasHeavy.sol'); @@ -87,6 +88,13 @@ const coins = [ nativeBatchPrefix: 'ARBETH-Batch', tokenPrefix: 'ARBETH-ERC20', WalletSimple: ArbethWalletSimple + }, + { + name: 'Opeth', + nativePrefix: 'OPETH', + nativeBatchPrefix: 'OPETH-Batch', + tokenPrefix: 'OPETH-ERC20', + WalletSimple: OpethWalletSimple } ]; From ded40bc2206919dad099e7d9f51437ed58cdd895 Mon Sep 17 00:00:00 2001 From: Akash Gianchandani Date: Mon, 30 Oct 2023 12:54:48 +0530 Subject: [PATCH 3/3] fix(eth-multisig-v4): fix failing test WIN-1013 --- test/gas.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/gas.js b/test/gas.js index aef1262..c837eba 100644 --- a/test/gas.js +++ b/test/gas.js @@ -178,7 +178,7 @@ describe(`Wallet Operations Gas Usage`, function () { it('WalletSimple send batch [ @skip-on-coverage ]', async function () { const gasUsageByBatchSize = [ - 101810, 113113, 124451, 135753, 147126, 158442, 169709, 181023, 192397, + 101810, 113113, 124451, 135753, 147126, 158442, 169709, 181023, 192338, 203641 ];