Omniscia Nexera Protocol Audit
BaseTxAuthDataVerifier Manual Review Findings
BaseTxAuthDataVerifier Manual Review Findings
BTA-01M: Incorrect Emittance of Event
Type | Severity | Location |
---|---|---|
Logical Fault | BaseTxAuthDataVerifier.sol:L147-L154 |
Description:
The NexeraIDSignatureVerified
event will be emitted even if the signature verification eventually fails.
Impact:
As the impact of this exhibit is off-chain, its severity cannot be quantified above informational
.
Example:
147emit NexeraIDSignatureVerified(148 block.chainid,149 userNonce,150 blockExpiration,151 address(this),152 userAddress,153 argsWithSelector154);155
156/// Verify Signature157if (158 !SignatureChecker.isValidSignatureNow(159 _signerAddress,160 ethSignedMessageHash,161 _signature162 )163) {164 revert InvalidSignature();165}166
167return true;
Recommendation:
We advise it to be emitted after the ensuing if
block to prevent off-chain software from triggering when signature validation has failed.
Alleviation:
After discussions with the Nexera Protocol team, we have concluded that the event's emittance prior to an error does not realistically impact its off-chain consumption and that the event should be emitted prior to the SignatureChecker
invocation due to potential downstream validations.
As such, we consider this exhibit as nullified given that it describes desirable behaviour.
BTA-02M: Improper Assumption of Calldata
Type | Severity | Location |
---|---|---|
Logical Fault | BaseTxAuthDataVerifier.sol:L119, L122-L123 |
Description:
The BaseTxAuthDataVerifier
signature verifier system expects the top-level function call to correctly specify the signature as the last argument of its function and to mutate its function signature to accommodate for the _signature
payload.
Both of these assumptions significantly hamper the applicability of the BaseTxAuthDataVerifier
due to non-compliancy of EIP function signatures and render it prone to errors, as introducing the signature to any location other than the end of the function's calldata will result in verifications failing.
Additionally, multiple dynamic arguments will be packed in calldata differently, causing the fixed _SIGNATURE_OFFSET
reduction to not work with them correctly.
Impact:
The present BaseTxAuthDataVerifier
is incompatible with EIPs as it will mutate their function signatures, and is prone to errors if integrators do not properly introduce the bytes memory
signature payload as the final argument of their function.
Additionally, the assumption presently introduced will fail to function as expected when multiple dynamic arguments are utilized.
Example:
97/**98 * @dev Verifies the authenticity and validity of a transaction's authorization data.99 * This function checks if the transaction signature is valid, has not expired, and is signed by the correct user.100 * It also ensures that the transaction has not been replayed by checking and incrementing the nonce.101 * Emits a {NexeraIDSignatureVerified} event upon successful verification.102 *103 * @param msgData The full calldata including the function selector and arguments.104 * @param userAddress The address of the user who signed the transaction.105 * @param blockExpiration The block number until which the transaction is considered valid.106 * @param _signature The signature of the user authorizing the transaction.107 * @return A boolean value indicating whether the transaction was successfully verified.108 *109 * Requirements:110 * - The current block number must be less than `blockExpiration`.111 * - The signature must be valid and correspond to `userAddress`.112 *113 * Emits a {NexeraIDSignatureVerified} event.114 */115function _verifyTxAuthData(116 bytes calldata msgData,117 address userAddress,118 uint256 blockExpiration,119 bytes memory _signature120) internal returns (bool) {121 /// Decompose msgData into the different parts we want122 bytes calldata argsWithSelector = msgData[:msgData.length -123 _SIGNATURE_OFFSET];
Recommendation:
We advise the signature payload to be injected instead, permitting data to be extracted efficiently and without mutating the top-level function signatures.
In detail, a low-level assembly
block can extract appended calldata that is not necessarily present in the top-level call, permitting EIP-compliant functions to still impose the authentication system designed by the Nexera Protocol.
Alleviation:
After extensive deliberation by the Nexera Protocol team, the mechanism we have proposed has been implemented in the codebase whereby calldata
is mutated off-chain by appending the relevant signature and block expiration argument with the on-chain code extracting these values by using offsets from the end of the call's msg.data
.
We consider the present implementation secure as it prevents injection of arbitrary data in between the function's actual payload and the signature validated due to the argsWithSelector
variable being assigned to the remainder of msg.data
that is not used as part of the signature verification process.
As such, we consider this exhibit fully alleviated.