1

I have an error when trying to use Recover function of ECDSA Library. What is the problem?

enter image description here

import "hardhat/console.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "./IToken.sol";
import "./BSCToken.sol";
import "./ETHToken.sol";
import "./TokenBase.sol";

contract Bridge {
    using ECDSA for bytes32;
    address public admin;
    TokenBase public token;
    uint256 public nonce;

    event SwapInitialized(
        address _from,
        address _to,
        uint256 _amount,
        uint256 _chainId,
        uint256 _nonce,
        string _symbol
    );

    constructor(address _token) {
        admin = msg.sender;
        token = TokenBase(_token);
    }

    function swap(
        address _to,
        uint256 _amount,
        uint256 _chainId,
        uint256 _nonce,
        string memory _symbol
    ) external {
        token.burn(msg.sender, _amount);
        emit SwapInitialized(
            msg.sender,
            _to,
            _amount,
            _chainId,
            _nonce,
            _symbol
        );
    }

    function reedem(
        address _to,
        uint256 _amount,
        uint256 _nonce,
        string memory _symbol,
        bytes32 _signatureV,
        bytes32 _signatureR,
        bytes32 _signatureS
    ) external {
        bytes32 signedDataHash = keccak256(
            abi.encodePacked(_to, _amount, _nonce, _symbol)
        );
        bytes32 message = signedDataHash.toEthSignedMessageHash();
        message.recover(_signatureV, _signatureR, _signatureS);
        token.mint(_to, _amount);
    }

}

1 Answer 1

2

You are probably looking for tryRecover as recover receives the combined signature as input:

message.tryRecover(_signatureV, _signatureR, _signatureS);

Edit: more complete example, using recover (not tested)

...
    address private _signerAddress = 0x123..;

    function _validSignature(bytes memory signature, bytes32 msgHash) internal view returns (bool) {
        return msgHash.toEthSignedMessageHash().recover(signature) == _signerAddress;
    }

    function reedem(
        address _to,
        uint256 _amount,
        uint256 _nonce,
        string memory _symbol,
        bytes memory signature
    ) external {
        bytes32 msgHash = keccak256(
            abi.encode(_to, _amount, _nonce, _symbol)
        );
        require(_validSignature(signature, msgHash), "INVALID_SIGNATURE");
        // note that this is still not secure, because the nonce
        // is user provided and doesn't change on-chain to signal
        // that it has been used by the user, also replay attacks..
        token.mint(_to, _amount);
    }

ethers.js:

  const signature = await signer.signMessage(
    ethers.utils.arrayify(
      ethers.utils.keccak256(
        ethers.utils.defaultAbiCoder.encode(['address', 'uint256', 'uint256', 'string'], [to, amount, nonce, symbol])
      )
    )
  );

I want to stress again, that this setup is absolutely not secure.

5
  • the same problem
    – ra1n89
    Commented Feb 21, 2022 at 19:09
  • _signatureV is supposed to be of type uint8
    – phaze
    Commented Feb 21, 2022 at 19:12
  • It didn't help(
    – ra1n89
    Commented Feb 21, 2022 at 19:20
  • updated with an example
    – phaze
    Commented Feb 21, 2022 at 19:27
  • Can you tell me how this line works: ` msgHash.toEthSignedMessageHash().recover(signature) ` as i know toEthSignedMessageHash() takes a parameter of messageHash and recover() takes mesage hash and signature , u are not passing it in function, how you are doing it?
    – Hacek
    Commented Apr 22, 2023 at 10:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.