diff --git a/pkg/hintrunner/hinter/scope.go b/pkg/hintrunner/hinter/scope.go index 3328e34b9..2f22b8c02 100644 --- a/pkg/hintrunner/hinter/scope.go +++ b/pkg/hintrunner/hinter/scope.go @@ -2,7 +2,6 @@ package hinter import ( "fmt" - "math/big" ) // ScopeManager handles all operations regarding scopes: @@ -88,38 +87,28 @@ func (sm *ScopeManager) GetVariableValue(name string) (any, error) { return nil, fmt.Errorf("variable %s not found in current scope", name) } -func (sm *ScopeManager) GetVariableValueAsBigInt(name string) (*big.Int, error) { +// GetVariableAs retrieves a variable from the current scope and asserts its type +func GetVariableAs[T any](sm *ScopeManager, name string) (T, error) { + var zero T // Zero value of the generic type value, err := sm.GetVariableValue(name) if err != nil { - return nil, err + return zero, err } - valueBig, ok := value.(*big.Int) + typedValue, ok := value.(T) if !ok { - return nil, fmt.Errorf("value: %s is not a *big.Int", value) - } - - return valueBig, nil -} + return zero, fmt.Errorf("value has a different type: value = %v, type = %T, expected type = %T", value, value, zero) -func (sm *ScopeManager) GetVariableValueAsUint64(name string) (uint64, error) { - value, err := sm.GetVariableValue(name) - if err != nil { - return 0, err } - valueUint, ok := value.(uint64) - if !ok { - return 0, fmt.Errorf("value: %s is not a uint64", value) - } - - return valueUint, nil + return typedValue, nil } func (sm *ScopeManager) getCurrentScope() (*map[string]any, error) { if len(sm.scopes) == 0 { return nil, fmt.Errorf("expected at least one existing scope") } + return &sm.scopes[len(sm.scopes)-1], nil } @@ -128,6 +117,7 @@ func (sm *ScopeManager) GetZeroDictionaryManager() (ZeroDictionaryManager, bool) if err != nil { return ZeroDictionaryManager{}, false } + dictionaryManager, ok := dictionaryManagerValue.(ZeroDictionaryManager) return dictionaryManager, ok } diff --git a/pkg/hintrunner/zero/zerohint_dictionaries.go b/pkg/hintrunner/zero/zerohint_dictionaries.go index d869c453c..cae271fe3 100644 --- a/pkg/hintrunner/zero/zerohint_dictionaries.go +++ b/pkg/hintrunner/zero/zerohint_dictionaries.go @@ -48,14 +48,10 @@ func newDictNewHint() hinter.Hinter { } } - initialDictValue, err := ctx.ScopeManager.GetVariableValue("initial_dict") + initialDict, err := hinter.GetVariableAs[map[fp.Element]memory.MemoryValue](&ctx.ScopeManager, "initial_dict") if err != nil { return err } - initialDict, ok := initialDictValue.(map[fp.Element]memory.MemoryValue) - if !ok { - return fmt.Errorf("value: %s is not a map[f.Element]mem.MemoryValue", initialDictValue) - } //> memory[ap] = __dict_manager.new_dict(segments, initial_dict) newDictAddr := dictionaryManager.NewDictionary(vm, initialDict) @@ -616,12 +612,11 @@ func newSquashDictInnerAssertLenKeysHint() hinter.Hinter { Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error { //> assert len(keys) == 0 - keys_, err := ctx.ScopeManager.GetVariableValue("keys") + keys, err := hinter.GetVariableAs[[]fp.Element](&ctx.ScopeManager, "keys") if err != nil { return err } - keys := keys_.([]fp.Element) if len(keys) != 0 { return fmt.Errorf("assertion `len(keys) == 0` failed") } @@ -661,16 +656,11 @@ func newSquashDictInnerCheckAccessIndexHint(loopTemps hinter.ResOperander) hinte //> ids.loop_temps.index_delta_minus1 = new_access_index - current_access_index - 1 //> current_access_index = new_access_index - currentAccessIndices_, err := ctx.ScopeManager.GetVariableValue("current_access_indices") + currentAccessIndices, err := hinter.GetVariableAs[[]fp.Element](&ctx.ScopeManager, "current_access_indices") if err != nil { return err } - currentAccessIndices, ok := currentAccessIndices_.([]fp.Element) - if !ok { - return fmt.Errorf("casting currentAccessIndices_ into an array of felts failed") - } - newAccessIndex, err := utils.Pop(¤tAccessIndices) if err != nil { return err @@ -681,16 +671,11 @@ func newSquashDictInnerCheckAccessIndexHint(loopTemps hinter.ResOperander) hinte return err } - currentAccessIndex_, err := ctx.ScopeManager.GetVariableValue("current_access_index") + currentAccessIndex, err := hinter.GetVariableAs[fp.Element](&ctx.ScopeManager, "current_access_index") if err != nil { return err } - currentAccessIndex, ok := currentAccessIndex_.(fp.Element) - if !ok { - return fmt.Errorf("casting currentAccessIndex_ into a felt failed") - } - err = ctx.ScopeManager.AssignVariable("current_access_index", newAccessIndex) if err != nil { return err @@ -746,16 +731,11 @@ func newSquashDictInnerContinueLoopHint(loopTemps hinter.ResOperander) hinter.Hi Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error { //> ids.loop_temps.should_continue = 1 if current_access_indices else 0 - currentAccessIndices_, err := ctx.ScopeManager.GetVariableValue("current_access_indices") + currentAccessIndices, err := hinter.GetVariableAs[[]fp.Element](&ctx.ScopeManager, "current_access_indices") if err != nil { return err } - currentAccessIndices, ok := currentAccessIndices_.([]fp.Element) - if !ok { - return fmt.Errorf("casting currentAccessIndices_ into an array of felts failed") - } - loopTempsAddr, err := loopTemps.GetAddress(vm) if err != nil { return err @@ -800,26 +780,16 @@ func newSquashDictInnerFirstIterationHint(rangeCheckPtr hinter.ResOperander) hin //> current_access_index = current_access_indices.pop() //> memory[ids.range_check_ptr] = current_access_index - key_, err := ctx.ScopeManager.GetVariableValue("key") + key, err := hinter.GetVariableAs[fp.Element](&ctx.ScopeManager, "key") if err != nil { return err } - accessIndices_, err := ctx.ScopeManager.GetVariableValue("access_indices") + accessIndices, err := hinter.GetVariableAs[map[fp.Element][]fp.Element](&ctx.ScopeManager, "access_indices") if err != nil { return err } - accessIndices, ok := accessIndices_.(map[fp.Element][]fp.Element) - if !ok { - return fmt.Errorf("cannot cast access_indices_ to a mapping of felts") - } - - key, ok := key_.(fp.Element) - if !ok { - return fmt.Errorf("cannot cast key_ to felt") - } - accessIndicesAtKey := accessIndices[key] accessIndicesAtKeyCopy := make([]fp.Element, len(accessIndicesAtKey)) @@ -879,16 +849,11 @@ func newSquashDictInnerSkipLoopHint(shouldSkipLoop hinter.ResOperander) hinter.H Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error { //> ids.should_skip_loop = 0 if current_access_indices else 1 - currentAccessIndices_, err := ctx.ScopeManager.GetVariableValue("current_access_indices") + currentAccessIndices, err := hinter.GetVariableAs[[]fp.Element](&ctx.ScopeManager, "current_access_indices") if err != nil { return err } - currentAccessIndices, ok := currentAccessIndices_.([]fp.Element) - if !ok { - return fmt.Errorf("casting currentAccessIndices_ into an array of felts failed") - } - shouldSkipLoopAddr, err := shouldSkipLoop.GetAddress(vm) if err != nil { return err @@ -927,12 +892,11 @@ func newSquashDictInnerLenAssertHint() hinter.Hinter { Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error { //> assert len(current_access_indices) == 0 - currentAccessIndices_, err := ctx.ScopeManager.GetVariableValue("current_access_indices") + currentAccessIndices, err := hinter.GetVariableAs[[]fp.Element](&ctx.ScopeManager, "current_access_indices") if err != nil { return err } - currentAccessIndices := currentAccessIndices_.([]fp.Element) if len(currentAccessIndices) != 0 { return fmt.Errorf("assertion `len(current_access_indices) == 0` failed") } @@ -958,12 +922,11 @@ func newSquashDictInnerNextKeyHint(nextKey hinter.ResOperander) hinter.Hinter { //> assert len(keys) > 0, 'No keys left but remaining_accesses > 0.' //> ids.next_key = key = keys.pop() - keys_, err := ctx.ScopeManager.GetVariableValue("keys") + keys, err := hinter.GetVariableAs[[]fp.Element](&ctx.ScopeManager, "keys") if err != nil { return err } - keys := keys_.([]fp.Element) if len(keys) == 0 { return fmt.Errorf("no keys left but remaining_accesses > 0") } @@ -1015,26 +978,16 @@ func newSquashDictInnerUsedAccessesAssertHint(nUsedAccesses hinter.ResOperander) Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error { //> assert ids.n_used_accesses == len(access_indices[key]) - accessIndices_, err := ctx.ScopeManager.GetVariableValue("access_indices") + accessIndices, err := hinter.GetVariableAs[map[fp.Element][]fp.Element](&ctx.ScopeManager, "access_indices") if err != nil { return err } - accessIndices, ok := accessIndices_.(map[fp.Element][]fp.Element) - if !ok { - return fmt.Errorf("cannot cast access_indices_ to a mapping of felts") - } - - key_, err := ctx.ScopeManager.GetVariableValue("key") + key, err := hinter.GetVariableAs[fp.Element](&ctx.ScopeManager, "key") if err != nil { return err } - key, ok := key_.(fp.Element) - if !ok { - return fmt.Errorf("cannot cast key_ to felt") - } - accessIndicesAtKeyLen := uint64(len(accessIndices[key])) nUsedAccesses, err := hinter.ResolveAsUint64(vm, nUsedAccesses) diff --git a/pkg/hintrunner/zero/zerohint_dictionaries_test.go b/pkg/hintrunner/zero/zerohint_dictionaries_test.go index 6f7bfaae3..4b2a8a184 100644 --- a/pkg/hintrunner/zero/zerohint_dictionaries_test.go +++ b/pkg/hintrunner/zero/zerohint_dictionaries_test.go @@ -45,11 +45,10 @@ func TestZeroHintDictionaries(t *testing.T) { t.Fatalf("incorrect apValue: %s expected %s", dictAddr.String(), "2:0") } - dictionaryManagerValue, err := ctx.runnerContext.ScopeManager.GetVariableValue("__dict_manager") + dictionaryManager, err := hinter.GetVariableAs[hinter.ZeroDictionaryManager](&ctx.runnerContext.ScopeManager, "__dict_manager") if err != nil { t.Fatalf("__dict_manager missing") } - dictionaryManager := dictionaryManagerValue.(hinter.ZeroDictionaryManager) for _, key := range []fp.Element{*feltUint64(10), *feltUint64(20), *feltUint64(30)} { value, err := dictionaryManager.At(dictAddr, key) @@ -78,12 +77,11 @@ func TestZeroHintDictionaries(t *testing.T) { return newDefaultDictNewHint(ctx.operanders["default_value"]) }, check: func(t *testing.T, ctx *hintTestContext) { - dictionaryManagerValue, err := ctx.runnerContext.ScopeManager.GetVariableValue("__dict_manager") + dictionaryManager, err := hinter.GetVariableAs[hinter.ZeroDictionaryManager](&ctx.runnerContext.ScopeManager, "__dict_manager") if err != nil { t.Fatalf("__dict_manager missing") } - dictionaryManager := dictionaryManagerValue.(hinter.ZeroDictionaryManager) apAddr := ctx.vm.Context.AddressAp() dictAddr, err := ctx.vm.Memory.ReadFromAddressAsAddress(&apAddr) if err != nil { diff --git a/pkg/hintrunner/zero/zerohint_ec.go b/pkg/hintrunner/zero/zerohint_ec.go index ab1f7b92c..9fe8e8b9f 100644 --- a/pkg/hintrunner/zero/zerohint_ec.go +++ b/pkg/hintrunner/zero/zerohint_ec.go @@ -96,7 +96,7 @@ func newNondetBigint3V1Hint(res hinter.ResOperander) hinter.Hinter { return err } - valueBig, err := ctx.ScopeManager.GetVariableValueAsBigInt("value") + valueBig, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "value") if err != nil { return err } @@ -249,10 +249,12 @@ func createFastEcAddAssignNewXHinter(resolver hintReferenceResolver) (hinter.Hin if err != nil { return nil, err } + point0, err := resolver.GetResOperander("point0") if err != nil { return nil, err } + point1, err := resolver.GetResOperander("point1") if err != nil { return nil, err @@ -277,23 +279,27 @@ func newFastEcAddAssignNewYHint() hinter.Hinter { Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error { //> value = new_y = (slope * (x0 - new_x) - y0) % SECP_P - slopeBig, err := ctx.ScopeManager.GetVariableValueAsBigInt("slope") + slopeBig, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "slope") if err != nil { return err } - x0Big, err := ctx.ScopeManager.GetVariableValueAsBigInt("x0") + + x0Big, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "x0") if err != nil { return err } - new_xBig, err := ctx.ScopeManager.GetVariableValueAsBigInt("new_x") + + new_xBig, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "new_x") if err != nil { return err } - y0Big, err := ctx.ScopeManager.GetVariableValueAsBigInt("y0") + + y0Big, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "y0") if err != nil { return err } - secPBig, err := ctx.ScopeManager.GetVariableValueAsBigInt("SECP_P") + + secPBig, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "SECP_P") if err != nil { return err } @@ -531,6 +537,7 @@ func createEcDoubleAssignNewXV1Hinter(resolver hintReferenceResolver) (hinter.Hi if err != nil { return nil, err } + point, err := resolver.GetResOperander("point") if err != nil { return nil, err @@ -555,23 +562,27 @@ func newEcDoubleAssignNewYV1Hint() hinter.Hinter { Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error { //> value = new_y = (slope * (x - new_x) - y) % SECP256R1_P - slopeBig, err := ctx.ScopeManager.GetVariableValueAsBigInt("slope") + slopeBig, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "slope") if err != nil { return err } - xBig, err := ctx.ScopeManager.GetVariableValueAsBigInt("x") + + xBig, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "x") if err != nil { return err } - new_xBig, err := ctx.ScopeManager.GetVariableValueAsBigInt("new_x") + + new_xBig, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "new_x") if err != nil { return err } - yBig, err := ctx.ScopeManager.GetVariableValueAsBigInt("y") + + yBig, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "y") if err != nil { return err } - secPBig, err := ctx.ScopeManager.GetVariableValueAsBigInt("SECP_P") + + secPBig, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "SECP_P") if err != nil { return err } @@ -714,6 +725,7 @@ func newEcMulInnerHint(scalar hinter.ResOperander) hinter.Hinter { if err != nil { return err } + scalarBytes := scalarFelt.Bytes() resultUint256 := new(uint256.Int).SetBytes(scalarBytes[:]) @@ -749,7 +761,7 @@ func newIsZeroNondetHint() hinter.Hinter { //> python hint in cairo file: "x == 0" //> compiled file hint: "memory[ap] = to_felt_or_relocatable(x == 0)" - x, err := ctx.ScopeManager.GetVariableValueAsBigInt("x") + x, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "x") if err != nil { return err } @@ -847,7 +859,7 @@ func newIsZeroDivModHint() hinter.Hinter { return fmt.Errorf("GetSecPBig failed") } - x, err := ctx.ScopeManager.GetVariableValueAsBigInt("x") + x, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "x") if err != nil { return err } @@ -968,18 +980,22 @@ func newRandomEcPointHint(p, m, q, s hinter.ResOperander) hinter.Hinter { if err != nil { return err } + pValues, err := vm.Memory.ResolveAsEcPoint(pAddr) if err != nil { return err } + mFelt, err := hinter.ResolveAsFelt(vm, m) if err != nil { return err } + qAddr, err := q.GetAddress(vm) if err != nil { return err } + qValues, err := vm.Memory.ResolveAsEcPoint(qAddr) if err != nil { return err @@ -991,6 +1007,7 @@ func newRandomEcPointHint(p, m, q, s hinter.ResOperander) hinter.Hinter { bytesArray = append(bytesArray, byteValue) } } + for _, felt := range pValues { writeFeltToBytesArray(felt) } @@ -1059,14 +1076,17 @@ func createRandomEcPointHinter(resolver hintReferenceResolver) (hinter.Hinter, e if err != nil { return nil, err } + m, err := resolver.GetResOperander("m") if err != nil { return nil, err } + q, err := resolver.GetResOperander("q") if err != nil { return nil, err } + s, err := resolver.GetResOperander("s") if err != nil { return nil, err diff --git a/pkg/hintrunner/zero/zerohint_others.go b/pkg/hintrunner/zero/zerohint_others.go index ef4c055f4..9d824a517 100644 --- a/pkg/hintrunner/zero/zerohint_others.go +++ b/pkg/hintrunner/zero/zerohint_others.go @@ -32,16 +32,12 @@ func newMemContinueHint(continueTarget hinter.ResOperander, memset bool) hinter. //> ids.continue_copying = 1 if n > 0 else 0 //> n-=1 - n, err := ctx.ScopeManager.GetVariableValue("n") + newN, err := hinter.GetVariableAs[uint64](&ctx.ScopeManager, "n") if err != nil { return err } - newN, ok := n.(uint64) - if !ok { - return fmt.Errorf("casting n into a uint64 failed") - } - newN = newN - 1 + newN -= 1 if err := ctx.ScopeManager.AssignVariable("n", newN); err != nil { return err @@ -219,13 +215,8 @@ func newFindElementHint(arrayPtr, elmSize, key, index, nElms hinter.ResOperander //> if '__find_element_index' in globals(): //> ids.index = __find_element_index - findElementIndex, err := ctx.ScopeManager.GetVariableValue("__find_element_index") + findElementIndex, err := hinter.GetVariableAs[uint64](&ctx.ScopeManager, "__find_element_index") if err == nil { - findElementIndex, ok := findElementIndex.(uint64) - if !ok { - return fmt.Errorf("invalid value for __find_element_index. Got: %v", findElementIndex) - } - findElementIndexFelt := new(fp.Element).SetUint64(findElementIndex) findElementIndexMemoryValue := memory.MemoryValueFromFieldElement(findElementIndexFelt) indexValAddr, err := index.GetAddress(vm) @@ -272,12 +263,9 @@ func newFindElementHint(arrayPtr, elmSize, key, index, nElms hinter.ResOperander //> assert n_elms <= __find_element_max_size, \ //> f'find_element() can only be used with n_elms<={__find_element_max_size}. ' \ //> f'Got: n_elms={n_elms}.' - findElementMaxSize, err := ctx.ScopeManager.GetVariableValue("__find_element_max_size") + + findElementMaxSize, err := hinter.GetVariableAs[uint64](&ctx.ScopeManager, "__find_element_max_size") if err == nil { - findElementMaxSize, ok := findElementMaxSize.(uint64) - if !ok { - return fmt.Errorf("invalid value for __find_element_max_size. Got: %v", findElementMaxSize) - } if nElms > findElementMaxSize { return fmt.Errorf("find_element() can only be used with n_elms<=%v. Got: n_elms=%v", findElementMaxSize, nElms) } diff --git a/pkg/hintrunner/zero/zerohint_signature.go b/pkg/hintrunner/zero/zerohint_signature.go index 7e85243ce..8114c5156 100644 --- a/pkg/hintrunner/zero/zerohint_signature.go +++ b/pkg/hintrunner/zero/zerohint_signature.go @@ -270,22 +270,22 @@ func newDivModSafeDivHint() hinter.Hinter { Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error { //> value = k = safe_div(res * b - a, N) - res, err := ctx.ScopeManager.GetVariableValueAsBigInt("res") + res, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "res") if err != nil { return err } - a, err := ctx.ScopeManager.GetVariableValueAsBigInt("a") + a, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "a") if err != nil { return err } - b, err := ctx.ScopeManager.GetVariableValueAsBigInt("b") + b, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "b") if err != nil { return err } - N, err := ctx.ScopeManager.GetVariableValueAsBigInt("N") + N, err := hinter.GetVariableAs[*big.Int](&ctx.ScopeManager, "N") if err != nil { return err } diff --git a/pkg/hintrunner/zero/zerohint_usort.go b/pkg/hintrunner/zero/zerohint_usort.go index 5a6d8bc8f..fcf5492bc 100644 --- a/pkg/hintrunner/zero/zerohint_usort.go +++ b/pkg/hintrunner/zero/zerohint_usort.go @@ -82,12 +82,11 @@ func newUsortBodyHint(input, inputLen, output, outputLen, multiplicities hinter. return err } - usortMaxSizeInterface, err := ctx.ScopeManager.GetVariableValue("__usort_max_size") + usortMaxSize, err := hinter.GetVariableAs[uint64](&ctx.ScopeManager, "__usort_max_size") if err != nil { return err } - usortMaxSize := usortMaxSizeInterface.(uint64) if inputLenValue > usortMaxSize { return fmt.Errorf("usort() can only be used with input_len<=%d.\n Got: input_len=%d", usortMaxSize, inputLenValue) } @@ -237,16 +236,11 @@ func newUsortVerifyHint(value hinter.ResOperander) hinter.Hinter { //> last_pos = 0 //> positions = positions_dict[ids.value][::-1] - positionsDictInterface, err := ctx.ScopeManager.GetVariableValue("positions_dict") + positionsDict, err := hinter.GetVariableAs[map[fp.Element][]uint64](&ctx.ScopeManager, "positions_dict") if err != nil { return err } - positionsDict, ok := positionsDictInterface.(map[fp.Element][]uint64) - if !ok { - return fmt.Errorf("casting positions_dict into an dictionary failed") - } - value, err := hinter.ResolveAsFelt(vm, value) if err != nil { return err @@ -294,16 +288,11 @@ func newUsortVerifyMultiplicityBodyHint(nextItemIndex hinter.ResOperander) hinte //> ids.next_item_index = current_pos - last_pos //> last_pos = current_pos + 1 - positionsInterface, err := ctx.ScopeManager.GetVariableValue("positions") + positions, err := hinter.GetVariableAs[[]uint64](&ctx.ScopeManager, "positions") if err != nil { return err } - positions, ok := positionsInterface.([]uint64) - if !ok { - return fmt.Errorf("cannot cast positionsInterface to []uint64") - } - currentPos, err := utils.Pop(&positions) if err != nil { return err @@ -314,16 +303,11 @@ func newUsortVerifyMultiplicityBodyHint(nextItemIndex hinter.ResOperander) hinte return err } - lastPosition, err := ctx.ScopeManager.GetVariableValue("last_pos") + lastPos, err := hinter.GetVariableAs[uint64](&ctx.ScopeManager, "last_pos") if err != nil { return err } - lastPos, ok := lastPosition.(uint64) - if !ok { - return fmt.Errorf("cannot cast last_pos to uint64") - } - // Calculate `next_item_index` memory value newNextItemIndexValue := currentPos - lastPos newNextItemIndexMemoryValue := memory.MemoryValueFromUint(newNextItemIndexValue) @@ -366,16 +350,11 @@ func newUsortVerifyMultiplicityAssertHint() hinter.Hinter { Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error { //> assert len(positions) == 0 - positionsInterface, err := ctx.ScopeManager.GetVariableValue("positions") + positions, err := hinter.GetVariableAs[[]uint64](&ctx.ScopeManager, "positions") if err != nil { return err } - positions, ok := positionsInterface.([]uint64) - if !ok { - return fmt.Errorf("casting positions into a []uint64 failed") - } - if len(positions) != 0 { return fmt.Errorf("assertion `len(positions) == 0` failed") }