56362 bc insight during addvalidation if pos not active authority native env state get should consume double the gas
Submitted on Oct 15th 2025 at 03:26:07 UTC by @emarai for Attackathon | VeChain Hayabusa Upgrade
Report ID: #56362
Report Type: Blockchain/DLT
Report severity: Insight
Target: https://github.com/vechain/thor/compare/master...release/hayabusa
Description
Brief / Intro
A commit on the release/hayabusa branch removed the gas charge charger.Charge(thor.SloadGas) before calling Authority.Native(..).Get():
if !isPoSActive {
- charger.Charge(thor.SloadGas) // a.getEntry(ValidatorMaster)
+
exists, endorser, _, _, err := Authority.Native(env.State()).Get(thor.Address(args.Validator))However, gas still needs to be charged since Authority.Native(..).Get() is not charging it internally. A similar call in authority_native.go explicitly charges twice the amount of gas:
{"native_isEndorsed", func(env *xenv.Environment) []any {
var nodeMaster common.Address
env.ParseArgs(&nodeMaster)
env.UseGas(thor.SloadGas * 2)
listed, endorsor, _, _, err := Authority.Native(env.State()).Get(thor.Address(nodeMaster))Relevant PR: https://github.com/vechain/thor/commit/f08442278f1eb45bae74f1fe922955c8e2f1d367
Impact Details
The gas that was supposed to be charged (200 or 400 if following authority_native.go) is not charged in the code path shown, resulting in lower gas consumption than intended.
References
https://github.com/vechain/thor/blob/b4c914fe573ed6141daa159fa293e9193a96d74f/builtin/authority_native.go#L72
https://github.com/vechain/thor/blob/b4c914fe573ed6141daa159fa293e9193a96d74f/builtin/staker_native.go#L189
Reproduce (modify code)
Remove or comment out the call to Authority.Native(env.State()).Get in builtin/staker_native.go to demonstrate that skipping the call does not change gas consumption:
--- a/builtin/staker_native.go
+++ b/builtin/staker_native.go
@@ -186,7 +186,10 @@ func init() {
}
if !isPoSActive {
- exists, endorser, _, _, err := Authority.Native(env.State()).Get(thor.Address(args.Validator))
+ // exists, endorser, _, _, err := Authority.Native(env.State()).Get(thor.Address(args.Validator))
+ // note: skipping the call to show that no gas is charged
+ exists := true
+ endorser := thor.Address(args.Endorser)
if err != nil {
return nil, err
}Run test
Execute the specific test to observe gas usage remains unchanged:
go test -timeout 30s -run ^TestStakerNativeGasCosts$ github.com/vechain/thor/v2/builtinExpected outcome: No difference in gas consumption when the Get call is removed, indicating the Authority.Native(env.State()).Get did not consume gas in that code path.
Was this helpful?