Transferencia ERC-20Defecto potencial de implementación... ¿o no?

Digamos que la transferFromfunción se implementa de la siguiente manera:

function transferFrom (address _from, address _to, uint256 _value)
public returns (bool success) {
   uint256 spenderAllowance = allowances [_from][msg.sender];
   if (spenderAllowance < _value) return false;
   uint256 fromBalance = accounts [_from];
   if (fromBalance < _value) return false;

   allowances [_from][msg.sender] = safeSub (spenderAllowance, _value);

   if (_value > 0 && _from != _to) {
     accounts [_from] = safeSub (fromBalance, _value);
     accounts [_to] = safeAdd (accounts [_to], _value);
   }
   Transfer (_from, _to, _value);
   return true;
}

Tal como lo veo, si _toes diferente a msg.senderobtendrá _totodos los tokens que se eliminarán de msg.senderla cantidad permitida.

Esta no debería ser la falla, prácticamente, porque nadie es lo suficientemente loco como para enviar su cantidad permitida a otra persona, pero ¿se puede usar de mala manera? ¿Cuáles son sus pensamientos sobre esto?

Hay un ataque bien conocido para aprobar/transferirDe cuando el remitente no tiene cuidado github.com/ethereum/EIPs/issues/738 . Hubo algunas implementaciones malas de ERC20 que fueron atacadas, pero por lo demás, la lógica resistió la prueba del tiempo. Tiene sus propias limitaciones y se presentaron otras alternativas como ERC223.

Respuestas (3)

El flujo transferFrom se define de alguna manera como:

// Send `tokens` amount of tokens from address `from` to address `to`
// The transferFrom method is used for a withdraw workflow, allowing contracts to send
// tokens on your behalf, for example to "deposit" to a contract address and/or to charge
// fees in sub-currencies; the command should fail unless the _from account has
// deliberately authorized the sender of the message via some mechanism; we propose
// these standardized APIs for approval:
function transferFrom(address _from, address _to, uint tokens) public returns (bool success) {
    balances[_from] = balances[_from].sub(tokens);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(tokens);
    balances[_to] = balances[_to].add(tokens);
    Transfer(_from, _to, tokens);
    return true;
}

Como puede ver, el objetivo es permitir que cualquier remitente de mensajes previamente aprobado para hacerlo (por _from , por supuesto), transfiera tokens de la cuenta _from a CUALQUIER cuenta _to que desee.

Msg.sender pagará tanto en términos de asignación como de gas para la transacción.

Por lo tanto, no hay lugar para trucos: msg.sender paga la gasolina y la asignación, _from gasta algunos tokens aprobados, _to recibe los tokens enviados por msg.sender .

En el caso de que no podamos tener este tipo de función, msg.sender debería transferir tokens a su propia cuenta primero (transacción en blockchain n.1) y, luego, enviarlos a _to account (transacción en blockchain n.2) . Entonces msg.sender paga su asignación Y el doble de la gasolina para la transacción.

Esto se puede evitar con el mecanismo transferFrom, que puede hacerlo usando solo una transacción de cadena de bloques y es más barato de realizar para msg.sender .

El comportamiento es intencionado. La idea de transferir desde es que un usuario permite que otro usuario mueva tokens. Dicho esto, el usuario que está autorizado puede hacer lo que quiera, es decir, enviarlo a su propia cuenta o enviarlo a otra persona.

Creo que su suposición principal de que "nadie está tan loco como para enviar su cantidad permitida a otra persona" no es cierta. En los casos en que desee enviar tokens a otro contrato como medio de pago, el contrato no estará al tanto de la transferencia de tokens, por lo que lo hace approveAndCall, luego el contrato de destino lo hará transferFromy podría enviar los tokens (por ejemplo) al propietario de ese contrato (una cuenta de propiedad externa). Así que trasnferFromes útil como es.

Espero que esto ayude.

Déjame responder en términos generales.

ERC20 es solo un estándar y puede pensarse como una interfaz. Una interfaz no dice nada sobre la implementación real.

Así que eres libre de codificar cualquier falla que desees en una función ERC20. Hay implementaciones de ejemplo que normalmente son seguras y hacen lo que se espera que haga la función, pero no necesita usar esas implementaciones para cumplir completamente con ERC20. Su token puede ser totalmente compatible con ERC20 con la implementación más tonta imaginable, siempre que las características de la función sean correctas.

Como dijiste, respuesta general, por lo que no responde mi pregunta. Este no es mi código y estoy intrigado si esto puede ser explotado. Pero dejó espacio para la siguiente pregunta... ¿por qué hay _to parámetro en absoluto? ¿Quizás conoce alguna referencia a alguna discusión sobre este tema antes de que se haya aceptado el ERC-20?
Eche un vistazo a los comentarios sobre la implementación en theethereum.wiki/w/index.php/ERC20_Token_Standard
Sí, claro, lo tengo. Solo tenía que leer esa página cuidadosamente en lugar de escribir una pregunta, pero espero que ayude a alguien :)