Uninitialized variables in ProofConsumer contract
ProofConsumer has no constructor or initializer; prover, nearTokenLocker, and minBlockAcceptanceHeight default to zero, making the contract unusable until set.
Description
The issue is found in the ProofConsumer contract, specifically affecting the variables prover, nearTokenLocker, and minBlockAcceptanceHeight.
The ProofConsumer contract lacks a constructor, resulting in the critical state variables prover, nearTokenLocker, and minBlockAcceptanceHeight being left uninitialized. This leads to:
- The
proverbeing set to the zero address. - The
nearTokenLockerbeing an empty byte array. - The
minBlockAcceptanceHeightbeing set to zero.
These uninitialized variables cause the _parseAndConsumeProof function to fail in various require statements, which are crucial for the proper validation and processing of proofs from the NEAR blockchain.
Impact
Uninitialized variables can cause significant operational issues, including:
- The contract will revert on critical functions due to failed validations, rendering it unusable.
- The
provervariable pointing toaddress(0)will cause theproveOutcomefunction to always fail, leading to the failure of any proof validation. - The
nearTokenLockerbeing empty will cause thekeccak256hash comparison to fail, preventing legitimate proofs from being accepted. - The
minBlockAcceptanceHeightdefaulting to zero will cause the height check in_parseAndConsumeProofto always revert, as the block height will always be considered "ancient."
Recommendation
Recommendations:
- Add a constructor: ensure all critical variables are properly initialized during contract deployment.
- Use initializers for upgradeable contracts: if the contract is intended to be upgradeable, use an initializer function instead of a constructor.
- Add setter functions: provide functions to set these variables if they need to be changed after deployment, with appropriate access control.
constructor(bytes memory _nearTokenLocker,INearProver _prover,uint64 _minBlockAcceptanceHeight) {require(_nearTokenLocker.length > 0, "Invalid Near Token Locker address");require(address(_prover) != address(0), "Invalid Near prover address");nearTokenLocker = _nearTokenLocker;prover = _prover;minBlockAcceptanceHeight = _minBlockAcceptanceHeight;}
function initialize(bytes memory _nearTokenLocker,INearProver _prover,uint64 _minBlockAcceptanceHeight) external initializer {require(_nearTokenLocker.length > 0, "Invalid Near Token Locker address");require(address(_prover) != address(0), "Invalid Near prover address");nearTokenLocker = _nearTokenLocker;prover = _prover;minBlockAcceptanceHeight = _minBlockAcceptanceHeight;}
function setProver(INearProver _prover) external onlyOwner {require(address(_prover) != address(0), "Invalid Near prover address");prover = _prover;}function setNearTokenLocker(bytes memory _nearTokenLocker) external onlyOwner {require(_nearTokenLocker.length > 0, "Invalid Near Token Locker address");nearTokenLocker = _nearTokenLocker;}function setMinBlockAcceptanceHeight(uint64 _minBlockAcceptanceHeight) external onlyOwner {minBlockAcceptanceHeight = _minBlockAcceptanceHeight;}
Resolution
Unresolved.

