I want to deposit erc20 tokens to a smart contract. But when I just send it to he address, I can't handle the deposit. So I tried to use the delegatecall
function to do the transfer.
Basically I thought of something like deposit(uint amount)
and the contract then handles the transaction.
I used this example to test if the delegatecall
works. The transferTo function should send the token from the sender to addr, but the function fails:
contract TokenInterface {
function transfer(address _to, uint _value) public returns (bool success);
}
contract New {
TokenInterface private token;
constructor(address tokenAddr)public{
token = TokenInterface(tokenAddr);
}
// This is just for testing. address(...).call(...) works fine
function echoBalance(address addr) public returns(uint balance){
(bool success, bytes memory result) = address(0x92...4f).call(abi.encodeWithSignature("balanceOf(address)", addr));
return abi.decode(result, (uint));
}
// but address(...).delegatecall(...) fails. Same when replaced by call
function transferTo(address addr, uint amount) public returns(bool success){
(bool success, bytes memory result) = address(0x92...4f).delegatecall(abi.encodeWithSignature("transfer(address,uint)", addr, amount));
return success;
//return token.transfer(addr, amount); // only transfers from this smart contract to addr, but not from sender
// addr would be the smart contract itself in the deposit scenario
}
}
The code is partially based o this post: ERC20 token withdrawal from smart contract
I tried it in remix.ethereum.org.
When I understand it right, .call
should send the token from the contracts address and .delegatecall
should send it from the msg.sender address.
The best way would be to use something like token.transfer(addr, amount)
but with senders address instead of the contracts address. Is this possible?
If not: how can I make the address(...).delegatecall(...) work?
Or is this scenario handled in another way?
I know that it can be done by using transferFrom
but this requires an additionnal approve
action by the caller, which I'd like to avoid.
EDIT:
I found out, that delegatecall
does not what I thought it would.
Is is possible to use one contract from another and act like the user who called the function, at all?
If not: Is it possible to do what i want to do?