Search code examples
ethereumsolidityremix

Delegatecall: function doesn't change a parentContract array element


I deployed two contracts (A,B). Function A.delegateUpdateIDX[contract_B,1] triggers function B.updateIDX[1]

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.4;

contract A {

string[] private arr = ['a','b','c'];

function showIDX(uint _IDX) public view returns(string memory)
    {
    return arr[_IDX];
    }

function delegateUpdateIDX(address _contractB, uint _IDX) external returns(bool _success)
    {
    (bool b,)=_contractB.delegatecall( abi.encodeWithSignature("updateIDX(uint _IDX)", _IDX) );
    return b;
    }
  
  
}

//###################################

contract B {
    
string[] private arr;

function updateIDX(uint _IDX) external
    {
    arr[_IDX]='X';
    }
    
}

Then I call functions (in Remix):

A.showIDX[1]
    returns 'b'

A.delegateUpdateIDX(B.address,1)
    no errors
    (should update A.storage and set A.arr[1] to 'X')
    but the delegateCall() returns 'success=false' for some reason
    and A.arr[1] doesn't change to 'X'

A.showIDX[1]
    returns 'b' again (not 'X' as expected)

So, basically, I have no idea why delegateCall() returns 'success=false' and therefore why doesn't A.arr[1] change from 'b' to 'X'. What am I doing wrong?


Solution

  • Managed to make it work

    1. abi.encodeWithSignature("updateIDX(uint _IDX)", _IDX) shouldn't have '_IDX' name in it, so I changed it to abi.encodeWithSignature("updateIDX(uint)", _IDX)

    -- it still didn't work, the delegateCall() kept returning 'false' --

    1. changed 'uint' to 'uint256' in both encodeWithSignature() and B.updateIDX()

    worked fine this time