3

I am trying to integrate ERC2721Context into my contract for use with Biconomy and am inheriting from ERC2721Context to my contract Test. Now, my contract Test is also inheriting from OpenZeppelin's contracts like AccessControl, ERC1155PresetMinterPauser, which also inherit from Openzeppelin's Context.

Since both Context and ERC2721Context have a function _msgSender(), I am getting an error "TypeError: Derived contract must override function "_msgSender". Two or more base classes define a function with the same name and parameter types.". Even though on biconomy's documentation it is stated to use ERC2771Context for such cases, this solution doesn't seem to work.

Is there any way around this problem, without bringing all the Openzeppelin's contracts that I am using offline, and manually removing inheritance from Context.sol?

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./ERC2771Context.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "./ERC1155PresetMinterPauser.sol";


contract TestingContract is ERC2771Context , ERC1155PresetMinterPauser{

    constructor (address _t) public ERC2771Context(_t) {
        
    }
    function versionRecipient() external  virtual view returns (string memory){
        return "1";
    }

}

The error :

TypeError: Derived contract must override function "_msgSender". Two or more base classes define function with same name and parameter types. --> contracts/TestingContract.sol:9:1: | 9 | contract TestingContract is ERC2771Context , ERC1155PresetMinterPauser{ | ^ (Relevant source part starts here and spans across multiple lines). Note: Definition in "Context": --> @openzeppelin/contracts/utils/Context.sol:17:5: | 17 | function _msgSender() internal view virtual returns (address) { | ^ (Relevant source part starts here and spans across multiple lines). Note: Definition in "ERC2771Context": --> contracts/ERC2771Context.sol:24:5: | 24 | function _msgSender() internal view virtual override returns (address) { | ^ (Relevant source part starts here and spans across multiple lines).

2 Answers 2

1

I finally was able to resolve the error by also overriding _msgSender() function in my TestingContract.

Added the following code to it:

function _msgSender() internal view override(Context, ERC2771Context) returns(address) {
        return ERC2771Context._msgSender();
} 

function _msgData() internal view override(Context, ERC2771Context) returns(bytes memory) 
{
        return ERC2771Context._msgData();
}
0

Integrate ERC2721 like this:-

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "../utils/Context.sol";

abstract contract ERC2771Context is Context {
    address private immutable _trustedForwarder;

    constructor(address trustedForwarder) {
        _trustedForwarder = trustedForwarder;
    }

    function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
        return forwarder == _trustedForwarder;
    }

    function _msgSender() internal view virtual override returns (address sender) {
        if (isTrustedForwarder(msg.sender)) {
            assembly {
                sender := shr(96, calldataload(sub(calldatasize(), 20)))
            }
        } else {
            return super._msgSender();
        }
    }

    function _msgData() internal view virtual override returns (bytes calldata) {
        if (isTrustedForwarder(msg.sender)) {
            return msg.data[:msg.data.length - 20];
        } else {
            return super._msgData();
        }
    }
}

note: import "../utils/Context.sol"; is openzeppelin part. install it if not coding in Remix online IDE

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.