Remediations for EIP-1283 reentrancy bug

Trying to provide a draft what #5 and #7 would look like.

#5:

    If current value equals new value (this is a no-op), 200 gas is deducted.
    If current value does not equal new value
        If original value equals current value (this storage slot has not been changed by the current execution context)
            If original value is 0, 20000 gas is deducted.
            Otherwise, 5000 gas is deducted. If new value is 0, add 15000 gas to refund counter.
        If original value does not equal current value (this storage slot is dirty). Apply all of the following clauses.
            Deduct 5000 gas, and add 4800 gas to refund counter.
            If original value is not 0
                If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0.
                If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter.
            If original value equals new value (this storage slot is reset)
                If original value is 0, add 19800 gas to refund counter.
                Otherwise, add 4800 gas to refund counter.

#7:

    If current value equals new value (this is a no-op).
        If current value is 0, and new value is not 0, deduct 20000 gas, and add 19800 gas to refund counter. Otherwise, deduct 5000 gas, and add 4800 gas to refund counter.
    If current value does not equal new value
        If original value equals current value (this storage slot has not been changed by the current execution context)
            If original value is 0, 20000 gas is deducted.
            Otherwise, 5000 gas is deducted. If new value is 0, add 15000 gas to refund counter.
        If original value does not equal current value (this storage slot is dirty). Apply all of the following clauses.
            If current value is 0, and new value is not 0, deduct 20000 gas, and add 19800 gas to refund counter. Otherwise, deduct 5000 gas, and add 4800 gas to refund counter.
            If original value is not 0
                If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0.
                If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter.
            If original value equals new value (this storage slot is reset)
                If original value is 0, add 19800 gas to refund counter.
                Otherwise, add 4800 gas to refund counter.

Both look like fine fix. But still, compared with #1, I have a slight feeling that this tries to preserve an invariant that we really didn’t have. This is an good thing to discuss whether we should preserve those as it’s about immutability. However, I want to note that any hard fork related to EVM would inevitably break at least those contracts that is designed specifically to be broken by it. (For example, any new opcode breaks a contract that just have this opcode byte, any gas cost change prevents an assertion that GAS must equal to a specific value.)

2 Likes