Imagine un contrato simple que cobra Eth. ¿Hay alguna forma de manipular esto de manera que después de que los usuarios envíen fondos, this.balance =/= max_val? ¿Se puede jugar esto de una manera que permita que isFinished() nunca pueda pasar la instrucción require?
uint max_val = 3 * 10** 18; // Can send up to 3 ETH
bool finished = false; // Not finished
// Function to send ETH
function sendEth() payable {
require(!finished); // Cannot be over
require(this.balance <= max_val); // Contribution must be less than or equal to contribution max
}
// Function to finish sending
function isFinished() {
require(!finished); // Cannot be finished. Cannot be called twice.
require(this.balance == max_val); // Must have collected max ETH
finished = true;
}
Un par de comentarios primero:
receiveEth
porque eso es lo que hace?Supongo que el saldo se actualiza después de la función, pero no estoy seguro (ver el comentario a continuación).
pragma solidity ^0.4.11;
contract Testing {
uint max_val = 3 * 10 ** 18;
bool finished = false;
modifier notFinished() {
if (finished)
revert();
_;
}
// NOTE: Not sure if this.balance is already updated with
// the new msg.value (my guess is no). I will edit this code
// if someone corrects me.
function receiveEth() notFinished() payable {
// If the tx would go over max, revert
if (msg.value + this.balance > max_val)
revert();
// If we will have exactly max, we're done
if (msg.value + this.balance == max_val)
finished = true;
// Otherwise, accept the eth
}
}
A juzgar por su código, es trivial enviar más que max_val
porque no verifica si msg.value
es más que max_value - this.balance
. Necesitas agregar require(msg.value <= max_value - this.balance)
adentro sendEth()
.
blockchaindotsol
sendEth()
se llama,this.balance
se actualiza, antes de pasar por cualquier línea de la función. Si este es el caso, ¿entonces norequire(msg.value <= max_value - this.balance)
sería redundante?guión