Skip to content

Commit

Permalink
fix: legacy-celo v/r/s black magic
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasbrugneaux committed Oct 2, 2023
1 parent ddd8d28 commit 71ae5fe
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 93 deletions.
92 changes: 31 additions & 61 deletions src/lib/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { accessListify, AccessListish } from "ethers/lib/utils";

// NOTE: Black magic
const Y_PARITY_EIP_2098 = 27;
const BULLSHIT_NUMBER = 8;

// From https://github.com/ethers-io/ethers.js/blob/master/packages/bytes/src.ts/index.ts#L33
// Copied because it doesn't seem to be exported from 'ethers' anywhere
Expand Down Expand Up @@ -352,42 +353,34 @@ export function serializeCeloTransaction(
// case that the signTransaction function only adds a v.
const sig = utils.splitSignature(signature);

let v = sig.v - Y_PARITY_EIP_2098;
let v: number;
if (txArgs.type) {
// cip64,cip42, eip-1559
// noop
v = sig.v - Y_PARITY_EIP_2098;
} else {
// celo-legacy
v = sig.v + chainId * 2 + 35;
v = Y_PARITY_EIP_2098 + sig.recoveryParam;

if (chainId !== 0) {
v += chainId * 2 + BULLSHIT_NUMBER;

// If an EIP-155 v (directly or indirectly; maybe _vs) was provided, check it!
if (sig.v > Y_PARITY_EIP_2098 + 1 && sig.v !== v) {
logger.throwArgumentError(
"transaction.chainId/signature.v mismatch",
"signature",
signature
);
}
} else if (sig.v !== v) {
logger.throwArgumentError(
"transaction.chainId/signature.v mismatch",
"signature",
signature
);
}
}

// TODO: rossy cleanup nico
// let v = 27 + sig.recoveryParam;
// if (chainId !== 0) {
// // NOTE: this makes the recoveryParam recovery custom in `parseCeloTransaction`
// // see line:
// if (txArgs.type) {
// // cip64,cip42, eip-1559
// } else {
// // celo-legacy
// v += chainId * 2 + 8;
// }

// // If an EIP-155 v (directly or indirectly; maybe _vs) was provided, check it!
// if (sig.v > 28 && sig.v !== v) {
// logger.throwArgumentError(
// "transaction.chainId/signature.v mismatch",
// "signature",
// signature
// );
// }
// } else if (sig.v !== v) {
// logger.throwArgumentError(
// "transaction.chainId/signature.v mismatch",
// "signature",
// signature
// );
// }
// @ts-expect-error
const raw = prepareEncodeTx(txArgs, { ...sig, v });
const encoded = utils.RLP.encode(raw);
Expand Down Expand Up @@ -484,34 +477,20 @@ export function parseCeloTransaction(

// EIP-155 unsigned transaction
if (handleNumber(tx.r).isZero() && handleNumber(tx.s).isZero()) {
tx.chainId = tx.v;
tx.v = 0;
if (!type) {
tx.chainId = tx.v;
tx.v = 0;
}
}
// Signed Transaction
else {
let chainId: number;
let recoveryParam = tx.v;
if (tx.type) {
// cip64, cip42, eip-1559
// noop, chainId is in tx
chainId = tx.chainId;
} else {
if (!type) {
// celo-legacy
chainId = Math.max(0, Math.floor((tx.v - 35) / 2));
tx.chainId = chainId;
recoveryParam = tx.v + Y_PARITY_EIP_2098;
recoveryParam -= tx.chainId * 2 + 35;
tx.chainId = Math.max(0, Math.floor((tx.v - 35) / 2));
recoveryParam = tx.v - Y_PARITY_EIP_2098;
recoveryParam -= tx.chainId * 2 + BULLSHIT_NUMBER;
}
// // NOTE: is this condition even correct now?
// if (!tx.chainId) {
// const chainId = Math.max(0, Math.floor((tx.v - 35) / 2));
// tx.chainId = chainId;
// }
// let recoveryParam = tx.v - 27;
// if (tx.chainId !== 0) {
// // NOTE: inverse operation that was done in `serializeCeloTransaction`
// recoveryParam -= tx.chainId * 2 + 8;
// }

// NOTE: Serialization needs to happen here because chainId may not populated before
const serialized = serializeCeloTransaction(
Expand All @@ -533,15 +512,6 @@ export function parseCeloTransaction(
tx.hash = utils.keccak256(rawTransaction);
}

console.log("---------");
console.log("Raw signed Tx", rawTransaction);
console.log("---------");
console.log("RLP decoded Tx", transaction);
console.log("---------");
console.log("Inferred type", type!);
console.log("---------");
console.log("Parsed TX from raw signed:", tx);
console.log("---------");
return tx;
}

Expand Down
57 changes: 25 additions & 32 deletions test/useContract.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import { BigNumber } from "ethers";
// import { CUSD_ADDRESS } from "./consts";
// import { STABLE_TOKEN_ABI } from "./stableToken";
import { getSigner } from "./utils";
import { BigNumber, Contract } from "ethers";
import { CUSD_ADDRESS } from "./consts";
// import { parseCeloTransaction } from "../src/lib/transactions";
// import { parseCeloTransaction } from "../src/lib/transactions";
import { STABLE_TOKEN_ABI } from "./stableToken";
import { getSigner } from "./utils";

async function main() {
const signer = getSigner();
// console.info("Getting account balance for:", signer.address);
// const balance = await signer.getBalance();
// console.info("Balance:", balance.toString());
console.info("Getting account balance for:", signer.address);
const balance = await signer.getBalance();
console.info("Balance:", balance.toString());

// console.info("Sending 1 CELO wei", signer.address);
// const txResponse1 = await signer.sendTransaction({
// to: signer.address,
// value: BigNumber.from("1"),
// });
console.info("Sending 1 CELO wei", signer.address);
const txResponse1 = await signer.sendTransaction({
to: signer.address,
value: BigNumber.from("1"),
});

// Or, alternatively, break apart signing and sending:
// const signedTx = await signer.signTransaction({
Expand All @@ -25,13 +22,9 @@ async function main() {
// });
// const provider = signer.provider;
// const txResponse1 = await provider.sendTransaction(signedTx);
// const txReceipt1 = await txResponse1.wait();
// console.info("Funds sent. Hash:", txReceipt1.transactionHash);
// console.log(
// parseCeloTransaction(
// "0x7bf88b82f37082050484313da74884362a38028301688c94325f890e573880311cfbadfe8ec3d51ffdd97a7687038d7ea4c6800080c09462492a644a588fd904270bed06ad52b9abfea1ae01a0920e75c798a225d5bd1b1e5c66babdc51943f39b32694d1819f99e5d33353b76a014473654adc9d03fe8de4fe275c1054b5b73d23095fecf7630e2b3a78322e0a2"
// )
// );
const txReceipt1 = await txResponse1.wait();
console.info("Funds sent. Hash:", txReceipt1.transactionHash);

console.info("Sending 1 CELO wei with cUSD feeCurrency");
const txResponse1feeCurrency = await signer.sendTransaction({
to: signer.address,
Expand All @@ -45,19 +38,19 @@ async function main() {
`CELO w/ feeCurrency payment hash: ${txReceipt1FeeCurency.transactionHash}`
);

// const stableToken = new Contract(CUSD_ADDRESS, STABLE_TOKEN_ABI, signer);
const stableToken = new Contract(CUSD_ADDRESS, STABLE_TOKEN_ABI, signer);

// console.info("Getting cUSD balance");
// const stableBalance = await stableToken.balanceOf(signer.address);
// console.info(`cUSD balance: ${stableBalance.toString()}`);
console.info("Getting cUSD balance");
const stableBalance = await stableToken.balanceOf(signer.address);
console.info(`cUSD balance: ${stableBalance.toString()}`);

// console.info("Sending 1 cUSD wei");
// const txResponse2 = await stableToken.transfer(
// signer.address,
// BigNumber.from("1")
// );
// const txReceipt2 = await txResponse2.wait();
// console.info(`cUSD payment hash: ${txReceipt2.transactionHash}`);
console.info("Sending 1 cUSD wei");
const txResponse2 = await stableToken.transfer(
signer.address,
BigNumber.from("1")
);
const txReceipt2 = await txResponse2.wait();
console.info(`cUSD payment hash: ${txReceipt2.transactionHash}`);
}

main()
Expand Down

0 comments on commit 71ae5fe

Please sign in to comment.