Project

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

Contract is unable to verify "Correctly signed" `Signatures` due to misimplementation in veryfing contract.

Summary

Contract is unable to verify "Correctly signed" Signatures due to lack of usage of toTypedMessageHash() in verification

function toTypedMessageHash() was declared in EIP712Base.sol, but not used in verification. This implies the following impact:

Impact

  • Contract is unable to verify a correctly signed signature. DOS for all accurately signed sigs

  • Contract is currently vulnerable to cross contract replay attack.

severity

High x High = High

Impact: High (DOS Sig)
Possibility: High (All correctly signed signatures are affected

POC

The following changes were made to codebase to enable testing in foundry:

  • function toTypedMessageHash made public to be accessible by test contract.

  • interface IMembershipFactory generated by foundry cast interface src/dao/MembershipFactory.sol:MembershipFactory.

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import {Test, console} from "forge-std/Test.sol";
import {MembershipFactory} from "../src/dao/MembershipFactory.sol";
//IMembershipFactory genarated from cast interface
import {NativeMetaTransaction,IMembershipFactory} from "./IMembershipFactory.sol";
import {CurrencyManager} from "../src/dao/CurrencyManager.sol";
import {MembershipERC1155} from "../src/dao/tokens/MembershipERC1155.sol";
contract MembershipFactoryTest is Test {
uint depositorPvKey;
address depositor;
MembershipERC1155 erc1155;
CurrencyManager currencyMgr;
IMembershipFactory factory;
string baseURI = "https://baseuri.com/";
address OpWallet = makeAddr("OpWallet");
function setUp() public {
(depositor,depositorPvKey) = makeAddrAndKey("Depositor");
erc1155 = new MembershipERC1155();
currencyMgr = new CurrencyManager();
factory = IMembershipFactory(address(new MembershipFactory(address(currencyMgr),OpWallet,baseURI,address(erc1155))));
}
function testSignatureVerificationImplementation() public{
uint nonce = factory.getNonce(depositor);
bytes memory FunctionSig = abi.encodeCall(IMembershipFactory.tiers,(depositor));
console.logBytes(FunctionSig);//0xc8111f27000000000000000000000000888d7213bfbfe01a4c88346eec0381e8903fba0a
bytes32 r;
bytes32 s;
uint8 v;
//sign sig
bytes32 correctDigest = computeACCURATEDigest(nonce,depositor,FunctionSig);
//bytes32 digest =computeINCORRECTDigestNoTypedHash(nonce,depositor,FunctionSig);
( v, r, s) = vm.sign(depositorPvKey, correctDigest);
bytes memory sig = abi.encodePacked(r, s, v);
assertEq(depositor,ecrecover(correctDigest, v, r, s));
//Prooves contract is unable to verify correcly signed signatures
vm.expectRevert();
factory.executeMetaTransaction(depositor,FunctionSig,r,s,v);
// However, the expected sig by the contract is the incorrect one with not typedHashed
// Displaying contract rather accepts incorrect Digests
bytes32 incorrectDigest = computeINCORRECTDigestNoTypedHash(nonce,depositor,FunctionSig);
(uint8 incorrectV, bytes32 incorrectR, bytes32 incorrectS) = vm.sign(depositorPvKey, incorrectDigest);
bytes memory IncorrectSig = abi.encodePacked(incorrectR,incorrectS,incorrectV);
factory.executeMetaTransaction(depositor,FunctionSig,incorrectR,incorrectS,incorrectV);
}
function computeACCURATEDigest(uint _nonce,address _signer, bytes memory _funcSig) internal returns(bytes32 ){
return factory.toTypedMessageHash(
computeINCORRECTDigestNoTypedHash(_nonce,_signer,_funcSig)
);
}
function computeINCORRECTDigestNoTypedHash(uint _nonce,address _signer, bytes memory _funcSig) internal returns(bytes32) {
return factory.hashMetaTransaction(
NativeMetaTransaction.MetaTransaction(
_nonce,
_signer,
_funcSig
)
);
}
}

Mitigation

function verify(
address signer,
MetaTransaction memory metaTx,
bytes32 sigR,
bytes32 sigS,
uint8 sigV
) internal view returns (bool) {
require(signer != address(0), "NativeMetaTransaction: INVALID_SIGNER");
return
signer ==
ecrecover(
- (hashMetaTransaction(metaTx)),
+ (toTypedMessageHash(hashMetaTransaction(metaTx))),
sigV,
sigR,
sigS
);
}
Updates

Lead Judging Commences

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

Appeal created

obincifer Submitter
7 months ago
0xbrivan2 Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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