ERC20 aprobar y transferir desde un contrato

Tengo un contrato con la siguiente función:

function offerTokenTribute(address[] _tokenContractAddresses, uint256[] _tokenTributes) public {
  require(_tokenContractAddresses.length == _tokenTributes.length);

  Member storage member = members[msg.sender];
  member.approved = false; // should be already, but lets be safe

  for (uint8 i = 0; i < _tokenContractAddresses.length; i++) {
    ERC20 erc20 = ERC20(_tokenContractAddresses[i]);
    erc20.approve(this, _tokenTributes[i]);
    member.tokenTributeAddresses.push(_tokenContractAddresses[i]);
    member.tokenTributeAmounts.push(_tokenTributes[i]);
  }

  TokenTributeOffered(msg.sender, _tokenContractAddresses, _tokenTributes);
}

El problema es que la erc20.approvefunción no está aprobando en nombre del remitente del mensaje original, está cambiando msg.sendera la dirección del contrato (verifiqué esto comprobando las asignaciones).

¿Hay alguna forma de hacer esto desde mi contrato, o la única solución es solicitar la aprobación fuera de mi contrato (no ideal)?

Respuestas (1)

No, no hay forma de evitarlo.

Es una característica de seguridad, un contrato no puede hacerse pasar por otra cuenta.

Sin embargo, un buen caso de uso puede requerir ejecutar en una sola transacción: Alice aprueba (Bob, 1000) Y Bob transfiere de (Alice a Charlie, 1000) ¿Cómo se puede hacer esto?
Permitir que un contrato se haga pasar por un usuario u otro contrato puede ser una pesadilla de seguridad a nivel de EVM si no se implementa correctamente. Es más práctico si se implementa a nivel de contrato, quizás se pueda usar ERC 777 para esa funcionalidad.