2

I have 3 libraries, one exposes struct and 2 others expose method with same signature/return type (first one provides default method implementation and second - extended and customized one). When trying to compile it I got error TypeError: Member "transfer" not unique after argument-dependent lookup in struct TypesLib.MyToken storage ref.

Is it possible to override function from one library in another? usings order change doesn't affects anything in my case.

Here is examples:

TypesLib.sol:

library TypesLib {
    struct TokenStorage {
.....
    }
}

DefaultLib.sol

import "./TypesLib.sol"

library DefaultLib {
    function transfer(TypesLib.TokenStorage storage self, address to, uint256 amount) public returns (bool) {
        ... default implementation ...
    }
}

CustomizedLib.sol

import "./TypesLib.sol"

library CustomLib {
    function transfer(TypesLib.TokenStorage storage self, address to, uint256 amount) public returns (bool) {
        ... custom implementation ...
    }
}

Contract.sol

import "./TypesLib.sol"
import "./DefaultLib.sol"
import "./CustomizedLib.sol"

library CustomLib {
    using DefaultLib for TypesLib.TokenStorage;
    using CustomizedLib for TypesLib.TokenStorage;

    TypesLib.TokenStorage token;

    function transfer(address to, uint256 amount) public returns (bool success) {
        return token.transfer(to, amount)
}
0

The problem is

using DefaultLib for TypesLib.TokenStorage;
using CustomizedLib for TypesLib.TokenStorage;

TypesLib.TokenStorage token; // which one??

It doesn't know which one you are trying to refer to. I think your structure may be a bit off. You only have 1 struct that you are using to store the data and you are getting it directly from TypesLib so just remove the using ... for lines and do a delegate call to the appropriate library.

import "./TypesLib.sol";
import { DefaultLib as Default } from "./DefaultLib.sol";
import { CustomLib as Customized } from "./CustomizedLib.sol";

// ...

library CustomLib {
    TypesLib.TokenStorage token;

    function transfer(address to, uint256 amount) public returns (bool success) {
        return Customized.transfer(token, to, amount);
    }
}

Per solidity docs:

The directive using A for B; can be used to attach library functions (from the library A) to any type (B)

Because the same type is being shared by both your Default and Custom lib, you only need to use the directive once and in that case you can remove the TypesLib import.

I would also suggest renaming the calling library (which looks more like a contract?) to avoid confusion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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