func pureMemoryGascost(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
	return memoryGasCost(mem, memorySize)
}
pureMemoryGascost is used by several operations, which aside from their
static cost have a dynamic cost which is solely based on the memory
expansion
package vm
import (
	"github.com/Dipper-Labs/Dipper-Protocol/app/v0/vm/common/math"
	sdk "github.com/Dipper-Labs/Dipper-Protocol/types"
	sdkerrors "github.com/Dipper-Labs/Dipper-Protocol/types/errors"
)
func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
	if newMemSize == 0 {
		return 0, nil
	}
	if newMemSize > 0x1FFFFFFFE0 {
		return 0, ErrGasUintOverflow
	}
	newMemSizeWords := toWordSize(newMemSize)
	newMemSize = newMemSizeWords * 32
	if newMemSize > uint64(mem.Len()) {
		square := newMemSizeWords * newMemSizeWords
		linCoef := newMemSizeWords * MemoryGas
		quadCoef := square / QuadCoeffDiv
		newTotalFee := linCoef + quadCoef
		fee := newTotalFee - mem.lastGasCost
		mem.lastGasCost = newTotalFee
		return fee, nil
	}
	return 0, nil
}
func memoryCopierGas(stackpos int) gasFunc {
	return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
		gas, err := memoryGasCost(mem, memorySize)
		if err != nil {
			return 0, err
		}
		words, overflow := bigUint64(stack.Back(stackpos))
		if overflow {
			return 0, ErrGasUintOverflow
		}
		if words, overflow = math.SafeMul(toWordSize(words), CopyGas); overflow {
			return 0, ErrGasUintOverflow
		}
		if gas, overflow = math.SafeAdd(gas, words); overflow {
			return 0, ErrGasUintOverflow
		}
		return gas, nil
	}
}
var (
	gasCallDataCopy   = memoryCopierGas(2)
	gasCodeCopy       = memoryCopierGas(2)
	gasExtCodeCopy    = memoryCopierGas(3)
	gasReturnDataCopy = memoryCopierGas(2)
)
func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
	if contract.Gas <= SstoreSentryGas {
		return 0, sdkerrors.Wrap(sdkerrors.ErrInternal, "not enough gas for reentrancy sentry")
	}
	var (
		y, x    = stack.Back(1), stack.Back(0)
		current = evm.StateDB.GetState(contract.Address(), sdk.BigToHash(x))
	)
	value := sdk.BigToHash(y)
	if current == value {  
		return SstoreNoopGas, nil
	}
	original := evm.StateDB.GetCommittedState(contract.Address(), sdk.BigToHash(x))
	if original == current {
		if original == (sdk.Hash{}) {  
			return SstoreInitGas, nil
		}
		if value == (sdk.Hash{}) {  
			evm.StateDB.AddRefund(SstoreClearRefund)
		}
		return SstoreCleanGas, nil  
	}
	if original != (sdk.Hash{}) {
		if current == (sdk.Hash{}) {  
			evm.StateDB.SubRefund(SstoreClearRefund)
		} else if value == (sdk.Hash{}) {  
			evm.StateDB.AddRefund(SstoreClearRefund)
		}
	}
	if original == value {
		if original == (sdk.Hash{}) {  
			evm.StateDB.AddRefund(SstoreInitRefund)
		} else {  
			evm.StateDB.AddRefund(SstoreCleanRefund)
		}
	}
	return SstoreDirtyGas, nil  
}
func gasSha3(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
	gas, err := memoryGasCost(mem, memorySize)
	if err != nil {
		return 0, err
	}
	wordGas, overflow := bigUint64(stack.Back(1))
	if overflow {
		return 0, ErrGasUintOverflow
	}
	if wordGas, overflow = math.SafeMul(toWordSize(wordGas), Sha3WordGas); overflow {
		return 0, ErrGasUintOverflow
	}
	if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
		return 0, ErrGasUintOverflow
	}
	return gas, nil
}