Skip to content

Commit

Permalink
contracts: improve EIP-155 test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
CedarMist committed Sep 18, 2023
1 parent f6582b4 commit a66d111
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
15 changes: 10 additions & 5 deletions clients/js/src/compat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -573,11 +573,13 @@ async function repackRawTx(
);
} catch (e) {
if (e instanceof EnvelopeError) throw e;
if (globalThis?.process?.env?.NODE_ENV !== 'test') {
console.trace(REPACK_ERROR);
}
}
const tx = ethers6.Transaction.from(raw);
if( tx.isSigned() && (!signer || await signer!.getAddress() != tx.from!) ) {
// us we are be unable to re-sign the encrypted tx, so must passthrough when
// they submit a transaction signed by another keypair
return tx.serialized;
}
const q = (v: bigint | null | undefined): string | undefined => {
if (!v) return undefined;
return ethers6.toQuantity(v);
Expand All @@ -592,14 +594,17 @@ async function repackRawTx(
value: q(tx.value),
chainId: Number(tx.chainId),
};
if (!signer) throw new CallError(REPACK_ERROR, null);
if (!parsed.gasLimit) parsed.gasLimit = q(BigInt(DEFAULT_GAS)); // TODO(39)
try {
return signer.signTransaction({
return signer!.signTransaction({
...parsed,
data: await cipher.encryptEncode(data),
});
} catch (e) {
// Many JSON-RPC providers, Ethers included, will not let you directly
// sign transactions, which is necessary to re-encrypt the calldata!
// Throw an error here to prevent calls which should've been encrypted
// from being submitted unencrypted.
throw new CallError(REPACK_ERROR, e);
}
}
Expand Down
1 change: 1 addition & 0 deletions contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@nomicfoundation/hardhat-chai-matchers": "^1.0.5",
"@nomiclabs/hardhat-ethers": "^2.1.1",
"@oasisprotocol/sapphire-hardhat": "workspace:^",
"@oasisprotocol/sapphire-paratime": "workspace:^",
"@openzeppelin/contracts": "^4.7.3",
"@typechain/ethers-v5": "^10.1.0",
"@typechain/hardhat": "^6.1.3",
Expand Down
54 changes: 51 additions & 3 deletions contracts/test/eip155.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { expect } from 'chai';
import { ethers } from 'hardhat';
import * as sapphire from '@oasisprotocol/sapphire-paratime'
import { EIP155Tests__factory } from '../typechain-types/factories/contracts/tests';
import { EIP155Tests } from '../typechain-types/contracts/tests/EIP155Tests';

Expand Down Expand Up @@ -29,7 +30,7 @@ describe('EIP-155', function () {
await testContract.deployed();
});

it('Wrapper encrypts transaction calldata', async function () {
it('Wrapper encrypts self-signed transaction calldata', async function () {
const tx = await testContract.example();
expect(entropy(tx.data)).gte(3.8);
expect(tx.data).not.eq(
Expand All @@ -38,9 +39,9 @@ describe('EIP-155', function () {
expect(tx.data.length).eq(218);
});

it('Signed transactions can be submitted', async function () {
it('Other-Signed transaction submission via un-wrapped provider', async function () {
const txobj = {
nonce: 0,
nonce: await testContract.provider.getTransactionCount(await testContract.publicAddr()),
gasPrice: await testContract.provider.getGasPrice(),
gasLimit: 250000,
to: testContract.address,
Expand All @@ -65,4 +66,51 @@ describe('EIP-155', function () {
'0xfedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210',
);
});

it('Other-Signed transaction submission via wrapped provider', async function () {
const txobj = {
nonce: await testContract.provider.getTransactionCount(await testContract.publicAddr()),
gasPrice: await testContract.provider.getGasPrice(),
gasLimit: 250000,
to: testContract.address,
value: 0,
data: '0x',
chainId: 0,
};
const signedTx = await testContract.sign(txobj);

let plainResp = await testContract.signer.provider!.sendTransaction(signedTx);
let receipt = await testContract.provider.waitForTransaction(
plainResp.hash,
);
expect(plainResp.data).eq(
testContract.interface.encodeFunctionData('example'),
);
expect(receipt.logs[0].data).equal(
'0xfedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210',
);
});

it('Self-Signed transaction submission via wrapped provider', async function () {
const p = testContract.provider;
const sk = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
const wallet = sapphire.wrap(new ethers.Wallet(sk).connect(p));
const calldata = testContract.interface.encodeFunctionData('example');

const signedTx = await wallet.signTransaction({
gasLimit: 250000,
to: testContract.address,
value: 0,
data: calldata,
chainId: (await p.getNetwork()).chainId,
gasPrice: (await p.getGasPrice()),
nonce: await p.getTransactionCount(wallet.address)
});

let x = await testContract.signer.provider!.sendTransaction(signedTx);
let r = await testContract.provider.waitForTransaction(x.hash);

expect(x.data).not.eq(calldata);
expect(r.logs[0].data).equal('0xfedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210');
});
});
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a66d111

Please sign in to comment.