Fixed error handling for contracts with receive and non-payable fallback.

This commit is contained in:
Richard Moore 2023-05-15 16:49:02 -04:00
parent f87f6ef9a0
commit 6db7458cf0
2 changed files with 16 additions and 6 deletions

View File

@ -436,13 +436,13 @@ describe("Test Contract Fallback", function() {
name: "receive and non-payable fallback",
address: "0x5b59d934f0d22b15e73b5d6b9ae83486b70df67e",
abi: [
"fallback() payable",
"fallback()",
"receive()"
],
sendNone: { data: "0x" },
sendData: { data: "0x" },
sendValue: { data: "0x" },
sendDataAndValue: { error: "overrides.value" },
sendDataAndValue: { error: "overrides" },
},
];
@ -489,7 +489,7 @@ describe("Test Contract Fallback", function() {
//console.log(result);
assert.ok(true);
} else {
assert.rejects(func, function(error: any) {
await assert.rejects(func, function(error: any) {
if (error.message === send.error) { return true; }
if (isError(error, "INVALID_ARGUMENT")) {
return error.argument === send.error;

View File

@ -172,13 +172,23 @@ function buildWrappedFallback(contract: BaseContract): WrappedFallback {
const iface = contract.interface;
const noValue = ((tx.value || BN_0) === BN_0);
const noData = ((tx.data || "0x") === "0x");
if (iface.fallback && !iface.fallback.payable && iface.receive && !noData && !noValue) {
assertArgument(false, "cannot send data to receive or send value to non-payable fallback", "overrides", overrides);
}
assertArgument(iface.fallback || noData,
"cannot send data to receive-only contract", "overrides.data", tx.data);
// Only allow payable contracts to set non-zero value
const payable = iface.receive || (iface.fallback && iface.fallback.payable);
assertArgument(payable || (tx.value || BN_0) === BN_0,
"cannot send value to non-payable contract", "overrides.value", tx.value);
assertArgument(payable || noValue,
"cannot send value to non-payable fallback", "overrides.value", tx.value);
// Only allow fallback contracts to set non-empty data
assertArgument(iface.fallback || (tx.data || "0x") === "0x",
assertArgument(iface.fallback || noData,
"cannot send data to receive-only contract", "overrides.data", tx.data);
return tx;