0

I'm trying to test if the delegatecall works fine, but I got an unwanted result.

contract CallerContract{
    uint256 public value;
    address public sender;
    string  public name;
    
    constructor() payable{
  
    }
    
    function testDelegateCall(string memory _name, TargetContractDelegate tc) public payable{
        value  = msg.value;
        sender = msg.sender;
        name   = _name;
        (bool success, bytes memory data) = payable(address(tc)).delegatecall(
            abi.encodeWithSelector(TargetContractDelegate.targetFunction.selector, "Some Name")
            );
    }
    
}

contract TargetContractDelegate{
    uint256 public value;
    address public sender;
    string  public name;
      
    function targetFunction(string memory _nameTarget) public payable{
        value       = msg.value;
        sender      = msg.sender;
        name        = _nameTarget;
    }

    function getValues() public view returns(string memory, address, uint) {
        return (name, sender, value);
    }
}

and my test file:

describe("Delegate Contract Testing...\n", function () {
    
    async function deployTokenFixture() {

        const [deployer] = await ethers.getSigners();

        const CallerContract = await ethers.getContractFactory("CallerContract");
        const callercontract = await CallerContract.deploy();
        await callercontract.deployed();
        
        const TargetContractDelegate = await ethers.getContractFactory("TargetContractDelegate");
        const targetcontract = await TargetContractDelegate.deploy();
        await targetcontract.deployed();
       
        return { 
            CallerContract,
            callercontract, 
            TargetContractDelegate, 
            targetcontract, 
            deployer
        }
    }

    describe("Deployment", function() {

       

        it("can call the target function a pass args", async function() {
            const { callercontract, targetcontract, deployer } = await loadFixture(deployTokenFixture);

            const tx = await callercontract.testDelegateCall(
                "Mensaje", targetcontract.address
                );

            console.log('==========================')
            //console.log(tx);

            const l = await targetcontract.getValues();
            console.log(l);
        });
    });
});

the console returns with:

[
  '',
  '0x0000000000000000000000000000000000000000',
  BigNumber { value: "0" }
]

1 Answer 1

1

take a look at the doc:

There exists a special variant of a message call, named delegatecall which is identical to a message call apart from the fact that the code at the target address is executed in the context of the calling contract (CallerContract in your case) and msg.sender and msg.value do not change their values.

that means that the contract state that will change when testDelegateCall is invoked is CallerContract state

you are checking the targetContractDelegate state

with:

const l = await targetcontract.getValues();

and that should remain without modifications after testDelegateCall invokation

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.