fix: estimate a request even when the site sends its gas limit (closes #554)
ethers asks the node for a gas estimate only when the request has no gas limit, and that estimate is the wallet's only check that a transaction does not revert. Since a site's `gas` became the gas limit, a reverting request carrying one opened the approval window and could be signed and mined to fail. Such a request is now estimated first, with the site's limit and under the same timeout; a failure goes back to the site with no window, and the site's gas limit is still the one shown and signed. A limit too low for the call now fails the same way. Model: opus-5-5
This commit was merged in pull request #557.
This commit is contained in:
@@ -201,6 +201,7 @@ async function prepareApprovalTx(provider, from, txParams) {
|
||||
throw fail("There is no active address to send this transaction from.");
|
||||
}
|
||||
const request = requestFrom(txParams || {}, from);
|
||||
const signer = new VoidSigner(getAddress(from), provider);
|
||||
|
||||
let populated;
|
||||
try {
|
||||
@@ -208,10 +209,20 @@ async function prepareApprovalTx(provider, from, txParams) {
|
||||
// nonce, gas, fee and chain id are populated exactly as they were when
|
||||
// the popup did this. VoidSigner cannot sign, which is the point: the
|
||||
// background prepares, the popup signs.
|
||||
//
|
||||
// ethers asks the node for a gas estimate only when the request has
|
||||
// no gas limit, and that estimate is the only check that the
|
||||
// transaction does not revert. So a request carrying the site's gas
|
||||
// limit is estimated first, with that limit: one that reverts, or
|
||||
// needs more gas than the site gave it, fails here as well. The
|
||||
// site's gas limit is still the one populated.
|
||||
populated = await withTimeout(
|
||||
new VoidSigner(getAddress(from), provider).populateTransaction(
|
||||
request,
|
||||
),
|
||||
(async () => {
|
||||
if (present(request.gasLimit)) {
|
||||
await signer.estimateGas(request);
|
||||
}
|
||||
return signer.populateTransaction(request);
|
||||
})(),
|
||||
POPULATE_TIMEOUT_MS,
|
||||
"The transaction could not be prepared: the network did not answer in time.",
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user