From ccf7c9a8f85ed5bdb0fe2f6a8304558a6d3f2b98 Mon Sep 17 00:00:00 2001 From: Adam Boudjemaa Date: Thu, 5 Mar 2026 11:55:31 +0100 Subject: [PATCH 1/2] fix(packer): use Uint64() to prevent silent overflow on GasAllocated --- .../plugins/ocr2keeper/evmregistry/v21/encoding/packer.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding/packer.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding/packer.go index ec84cd37f4b..db58ca85fff 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding/packer.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding/packer.go @@ -45,10 +45,16 @@ func (p *abiPacker) UnpackCheckResult(payload ocr2keepers.UpkeepPayload, raw str fmt.Errorf("upkeepId %s failed to unpack checkUpkeep result %s: %w", payload.UpkeepID.String(), raw, err) } + gasAllocatedBig := *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + if !gasAllocatedBig.IsUint64() { + return GetIneligibleCheckResultWithoutPerformData(payload, UpkeepFailureReasonNone, PackUnpackDecodeFailed, false), + fmt.Errorf("upkeepId %s GasAllocated value %s overflows uint64", payload.UpkeepID.String(), gasAllocatedBig.String()) + } + result := ocr2keepers.CheckResult{ Eligible: *abi.ConvertType(out[0], new(bool)).(*bool), Retryable: false, - GasAllocated: uint64((*abi.ConvertType(out[4], new(*big.Int)).(**big.Int)).Int64()), + GasAllocated: gasAllocatedBig.Uint64(), UpkeepID: payload.UpkeepID, Trigger: payload.Trigger, WorkID: payload.WorkID, From 875fbcb61f859d12548a8bf25b4e3f80768cd439 Mon Sep 17 00:00:00 2001 From: Adam Boudjemaa Date: Thu, 5 Mar 2026 17:38:00 +0100 Subject: [PATCH 2/2] test(packer): add unit test for GasAllocated overflow --- .../evmregistry/v21/encoding/packer_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding/packer_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding/packer_test.go index 92bec6003ec..23ee7923041 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding/packer_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding/packer_test.go @@ -184,6 +184,19 @@ func TestPacker_UnpackCheckResults(t *testing.T) { }, ExpectedError: fmt.Errorf("upkeepId %s failed to unpack checkUpkeep result 0x123123: abi: cannot marshal in to go type: length insufficient 3 require 32", p2.UpkeepID.String()), }, + { + Name: "gas allocated overflow", + Payload: p1, + // valid checkUpkeep encoding with GasAllocated set to math.MaxUint64+1 (2^64) + RawData: "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000421c0000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000c8caf37f3b3890000000000000000000000000000000000000000000000000000000000000000", + ExpectedResult: ocr2keepers.CheckResult{ + UpkeepID: upkeepId, + PipelineExecutionState: uint8(PackUnpackDecodeFailed), + Trigger: p1.Trigger, + WorkID: p1.WorkID, + }, + ExpectedError: fmt.Errorf("upkeepId %s GasAllocated value 18446744073709551616 overflows uint64", p1.UpkeepID.String()), + }, } for _, test := range tests { t.Run(test.Name, func(t *testing.T) {