Let's suppose I have the two following contracts, Dest and Proxy:
pragma solidity ^0.5.0; contract Dest { function foo(string memory name, string memory symbol, uint256 decimals, uint256 totalSupply, address sender, uint256 value) public { /* * Logic code Here */ } function bar(address a, address b, address c, address d, uint256 e, address f, address sender, uint256 value) public { /* * Logic code Here */ } } contract Proxy { address private _owner; address private _dest; constructor(address dest) public { _owner = msg.sender; _dest = dest; } function getDest() public view returns(address) { return _dest; } function setDest(address dest) public { require(msg.sender == _owner); _dest = dest; } // Invoke takes msg.sender and msg.value and concatenates both to payload before to call the correct method function invoke(string memory method, bytes memory data) public payable { bytes memory payload = abi.encodePacked(bytes4(keccak256(bytes(method)))), data, abi.encode(msg.sender), abi.encode(msg.value)); (bool ok, bytes memory response) = _dest.call(payload); } } Both foo and bar methods in Dest contract have address sender, uint256 value as final input parameters.
The logic is that users will call Proxy passing the complete method signature and all abi encoded parameters except for the last two.
Proxy sequentially packs together method signature, partial call parameters, msg.sender and msg.value in a unique bytes packed payload, then invokes the call method on the Dest address using the packed payload as input.
The problem is that when the foo method is called, the value of sender input parameter is not the original msg.sender address, but contains some inconsistent value.
But everything works fine when the bar method is called.
My suspicion is that the problem is related to the fact that in the head of the input parameters of the foo method there are strings, which have variable length, while in bar there are only parameters with fixed length.
Any suggestion on how to build a general purpose solution?