How to Check New Parameter Values Before a Governance Proposal Executes

 / 
5

When a governance proposal is queued for execution, the most reliable way to find out what the parameters will be changed to is not to read the proposal text, but to decode the pending calldata directly from the timelock contract. Text on the frontend can be outdated, shortened, or intentionally misleading. Only the raw on-chain data does not lie.

OKX Exchange
A leading global cryptocurrency platform,suitable for both beginners and experienced traders.
New user benefit: 20% off trading fees upon registration!!

Below is a step-by-step approach using Compound governance on Ethereum and Etherscan as an example. The same logic works on other EVM chains and similar DAO tools.

Step 1: Confirm the proposal is in the Timelock queue and get the transaction data

You need to find the "queued transaction" for the proposal, not just the voting results. A passed vote only means it can enter the queue. Without queuing, there are no pending parameters to decode.

How to do it:

  • Option A: Use a governance dashboard (such as Tally or Sybil)

Open the proposal page and check if the status is Queued or similar. Find the "Execution Transaction" section, which usually shows three raw fields: target, value, and data. Copy these three fields directly.

  • Option B: Pull data directly from the on-chain Timelock contract

If no dashboard is available, go to the block explorer and find the Timelock contract (e.g., Compound's Timelock at 0x6d903f6003cca6255D85CcA4D3B5E5146dC33925, source: Compound docs, April 2025). Inside the contract, look for events from the queueTransactions function, or call read-only methods such as getQueueLength or queuedTransactions. Use the transaction index of the proposal to extract target, value, and data.

What you need: At least one raw data string (a hex string starting with 0x). This is the actual instruction that will be sent to the target contract upon execution.

Common mistake: Many people treat screenshots of "parameters in the proposal" as the final truth, only to find out at execution that the screenshot does not match the on-chain calldata. Screenshots can be easily faked at the UI level, while calldata is locked inside the queued transaction and cannot be changed without a private key.

Step 2: Decode the calldata and read every new parameter value

In this step, you turn the raw data from Step 1 into human-readable parameter names and values.

How to do it:

  • Identify the target contract address – that is the target from Step 1.
  • Paste the target contract address into Etherscan, then go to "Contract" → "Write as Proxy" or "Write Contract" (if the contract is verified and open-source).
  • Click "Input Data Decoder" or a similar entry (the position varies by explorer). Paste the data and decode it. If Etherscan does not have a built-in decoder, use an online ABI tool by feeding it the contract ABI and the data string.
  • After decoding, you will see a function name (e.g., _setInterestRateModel) and each parameter's value. The new interest rate coefficient, collateral factor, or fee percentage will be listed as numbers.

Branching cases:

  • Target contract is not open-source or not verified: Decode offline using the full ABI. You can get the ABI from the protocol's official GitHub and parse it with eth-abi tools or something like CyberChef. This requires more effort, but the data is still readable.
  • Governance uses OpenZeppelin TimelockController: Many projects batch multiple actions inside scheduleBatch. In this case, you first need to split the full calldata by array offsets and then decode each segment. The idea is the same, just with one extra unpacking step.

What you get: A clear list of parameters, such as "multiplierPerBlock: 228310502283105" or "newLiquidationThreshold: 8000" (meaning 80%). These numbers will take effect immediately after execution.

Risk reminder: The proposal's title and description can deviate from the actual calldata. There have been malicious proposals that claimed to "lower fees" while the calldata set fees to the maximum. If you vote without verifying the decoded data, you are essentially outsourcing your asset safety to the proposal text. Addresses that hold a large amount of governance tokens, in particular, create a backdoor for social engineering attacks if they do not check the calldata.

OKX Exchange
A leading global cryptocurrency platform,suitable for both beginners and experienced traders.
New user benefit: 20% off trading fees upon registration!!

Step 3: Compare with the current on-chain values to see the actual change

Even after decoding the values, you must compare the new and old values on the same basis to avoid unit mistakes (e.g., wei vs. decimal representation, or annual rate vs. per-block rate).

How to do it:

  • On the target contract, call the read-only method that corresponds to what the proposal is changing (e.g., liquidationThreshold, borrowRatePerBlock) to get the current parameter.
  • Subtract the current value from the new value you decoded in Step 2 to find the absolute and relative difference.
  • If the change involves an interest rate model upgrade (e.g., switching from JumpRateModelV2 to a custom model), also verify that the new model contract's logic matches the description. If needed, simulate a transaction on Tenderly by forking the state.

What you get: A clear understanding that the parameter will change from X to Y, a change of Z%. You can also judge whether the change falls within the range claimed by the proposal.

Risk reminder: Parameter changes usually come with a timelock delay (Compound's is 48 hours, source: Compound Timelock, April 2025). If you do not re-check the calldata during the waiting period before execution, a malicious action could be added or the transaction could be replaced through a multi-sig (depending on the Timelock implementation). It is wise to verify again close to the execution time.

Next step: Verify immediately after execution

After you have confirmed the calldata is correct and the timelock expires, anyone can trigger the execution (usually by paying gas). Do not assume that the new value is automatically in place. Wait for a reasonable number of block confirmations on the execution transaction (for Ethereum, 12 confirmations, about 3 minutes), then immediately read the target contract's parameter again. Compare it with the new value from Step 3. Use the block explorer's contract read function or send a read-only call from your wallet; this normally takes less than a minute. If the value has not changed, the execution transaction may have failed or the calldata may have been sent to the wrong target contract. Do not perform any on-chain on-chain operations linked to these parameters until you have checked the execution transaction's status.