From bae7565231376bbd23474e2e91c99a21542ef47a Mon Sep 17 00:00:00 2001
From: Martin Holst Swende <martin@swende.se>
Date: Wed, 28 Jun 2017 09:51:31 +0200
Subject: [PATCH] core/vm: fix overflow in gas calculation formula

---
 core/vm/gas_table.go | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go
index 24ad6caa52..761ca44507 100644
--- a/core/vm/gas_table.go
+++ b/core/vm/gas_table.go
@@ -17,7 +17,6 @@
 package vm
 
 import (
-	gmath "math"
 	"math/big"
 
 	"github.com/ethereum/go-ethereum/common"
@@ -28,15 +27,20 @@ import (
 // memoryGasCosts calculates the quadratic gas for memory expansion. It does so
 // only for the memory region that is expanded, not the total memory.
 func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
-	// The maximum that will fit in a uint64 is max_word_count - 1
-	// anything above that will result in an overflow.
-	if newMemSize > gmath.MaxUint64-32 {
-		return 0, errGasUintOverflow
-	}
 
 	if newMemSize == 0 {
 		return 0, nil
 	}
+	// The maximum that will fit in a uint64 is max_word_count - 1
+	// anything above that will result in an overflow.
+	// Additionally, a newMemSize which results in a
+	// newMemSizeWords larger than 0x7ffffffff will cause the square operation
+	// to overflow.
+	// The constant 0xffffffffe0 is the highest number that can be used without
+	// overflowing the gas calculation
+	if newMemSize > 0xffffffffe0 {
+		return 0, errGasUintOverflow
+	}
 
 	newMemSizeWords := toWordSize(newMemSize)
 	newMemSize = newMemSizeWords * 32