Project

One World
NFTDeFi
15,000 USDC
View results
Submission Details
Severity: medium
Invalid

NativeMetaTransaction::executeMetaTransaction() transactions are very likely to revert

Summary

NativeMetaTransaction::executeMetaTransaction() transactions are very likely to revert due to not appending relayer address at the end of functionSignature.

Vulnerability Details

The NativeMetaTransaction::executeMetaTransaction function when executing, makes a call to a function given via its functionSignature argument. About that call, the documentation in code comments stipulates this:

// Append userAddress and relayer address at the end to extract it from calling context

However, while userAddress is appended at the end of functionSignature, the relayer address is not.

File: /contracts/meta-transaction/NativeMetaTransaction.sol#L33-L68
function executeMetaTransaction(
address userAddress,
bytes memory functionSignature,
bytes32 sigR,
bytes32 sigS,
uint8 sigV
) public payable returns (bytes memory) {
MetaTransaction memory metaTx = MetaTransaction({
nonce: nonces[userAddress],
from: userAddress,
functionSignature: functionSignature
});
require(
verify(userAddress, metaTx, sigR, sigS, sigV),
"Signer and signature do not match"
);
// increase nonce for user (to avoid re-use)
nonces[userAddress] = nonces[userAddress] + 1;
emit MetaTransactionExecuted(
userAddress,
msg.sender,
functionSignature,
hashMetaTransaction(metaTx)
);
// Append userAddress and relayer address at the end to extract it from calling context
(bool success, bytes memory returnData) = address(this).call{value: msg.value}(
@--> abi.encodePacked(functionSignature, userAddress)
);
require(success, "Function call not successful");
return returnData;
}

This can lead to a failling extraction in the calling context and makes the transaction revert.

Impact

NativeMetaTransaction::executeMetaTransaction() transactions are very likely to revert.

Tools Used

Manual review.

Recommendations

Append the relayer address at the end of functionSignature as specified in the documentation.

File: /contracts/meta-transaction/NativeMetaTransaction.sol#L33-L68
function executeMetaTransaction(
address userAddress,
bytes memory functionSignature,
bytes32 sigR,
bytes32 sigS,
uint8 sigV
) public payable returns (bytes memory) {
MetaTransaction memory metaTx = MetaTransaction({
nonce: nonces[userAddress],
from: userAddress,
functionSignature: functionSignature
});
require(
verify(userAddress, metaTx, sigR, sigS, sigV),
"Signer and signature do not match"
);
// increase nonce for user (to avoid re-use)
nonces[userAddress] = nonces[userAddress] + 1;
emit MetaTransactionExecuted(
userAddress,
msg.sender,
functionSignature,
hashMetaTransaction(metaTx)
);
// Append userAddress and relayer address at the end to extract it from calling context
(bool success, bytes memory returnData) = address(this).call{value: msg.value}(
-- abi.encodePacked(functionSignature, userAddress)
++ abi.encodePacked(functionSignature, userAddress, msg.sender)
);
require(success, "Function call not successful");
return returnData;
}
Updates

Lead Judging Commences

0xbrivan2 Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.