Skip to content

Conversation

yash-atreya
Copy link
Member

Motivation

Ref: #11276 (comment)

The current approach would not identify storage changes on proxy contracts.

Solution

  • Identify whether the account being accessed is a proxy or not.
  • We can do this by checking whether the bytecode contains one of the two EIP1967_IMPL_SLOT or EIP1822_PROXIABLE_SLOT
  • Find the artifact accordingly
  • Unify get_contract_name into get_contract_data since they do the same thing

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

@yash-atreya
Copy link
Member Author

yash-atreya commented Aug 22, 2025

@sakulstra ptal, this should fix it. Tested locally and I was able to get

{
  "0xdabad81af85554e9ae636395611c58f7ec1aaec5": {
    "label": null,
    "contract": "lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy",
    "balanceDiff": null,
    "nonceDiff": null,
    "stateDiff": {
      "0xf3e9bdb17e809d40894019e71fc3cd1caab638876c2f7e53420abc45924bfed5": {
        "previousValue": "0x006839b936000000000002000000000000000000000000000000000000000000",
        "newValue": "0x006839b936000000000003000000000000000000000000000000000000000000"
      },
      "0xf3e9bdb17e809d40894019e71fc3cd1caab638876c2f7e53420abc45924bfed6": {
        "previousValue": "0x000000000000000000093a800000000000006867ddb700000000000000000000",
        "newValue": "0x000000000000000000093a800000000000006867ddb70000000000006839b937"
      }
    }
  }
}

@yash-atreya yash-atreya changed the title fix(cheatcodes): identify proxies in state diffs fix(cheatcodes): identify common proxies in state diffs Aug 22, 2025
@yash-atreya yash-atreya self-assigned this Aug 22, 2025
@yash-atreya yash-atreya moved this to Ready For Review in Foundry Aug 22, 2025
@yash-atreya yash-atreya added C-forge Command: forge A-cheatcodes Area: cheatcodes T-bug Type: bug labels Aug 22, 2025
@yash-atreya yash-atreya changed the title fix(cheatcodes): identify common proxies in state diffs fix(cheatcodes): identify common proxies in state diffs Aug 22, 2025
@yash-atreya yash-atreya marked this pull request as ready for review August 22, 2025 12:16
@sakulstra
Copy link
Contributor

@yash-atreya I'm not 100% sure it's as desired, but our needs might not be what foundry needs 😅

What we get on tenderly, is for every state changed:

  • we get the decoded state
  • we get the contract name (even if not available in the local file tree)

For proxies:

  • we get the information that it's a proxy
  • we get the information on what is the impl
  • the state gets decoded based on the impl

I know far to little about the internals to understand if that's even possible.
My guess was just that based on the trace being able to decode:

 ├─ [6954] TransparentUpgradeableProxy::fallback(296) [staticcall]
    │   ├─ [6008] PayloadsController::getPayloadById(296) [delegatecall]
    │   │   └─ ← [Return] Payload({ creator: 0x0000000000000000000000000000000000000000, maximumAccessLevelRequired: 0, state: 1, createdAt: 0, queuedAt: 0, executedAt: 0, cancelledAt: 0, expirationTime: 1751637431 [1.751e9], delay: 0, gracePeriod: 604800 [6.048e5], actions: [ExecutionAction({ target: 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f, withDelegateCall: true, accessLevel: 1, value: 0, signature: "execute()", callData: 0x })] })
    │   └─ ← [Return] Payload({ creator: 0x0000000000000000000000000000000000000000, maximumAccessLevelRequired: 0, state: 1, createdAt: 0, queuedAt: 0, executedAt: 0, cancelledAt: 0, expirationTime: 1751637431 [1.751e9], delay: 0, gracePeriod: 604800 [6.048e5], actions: [ExecutionAction({ target: 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f, withDelegateCall: true, accessLevel: 1, value: 0, signature: "execute()", callData: 0x })] })

You already fetched the abi/code from etherscan as on the trace you know that 0xdabad81af85554e9ae636395611c58f7ec1aaec5 is a TransparentUpgradeableProxy with the impl of PayloadsController (and i think the impl should not by in my local filesystem)

Copy link
Contributor

@0xrusowsky 0xrusowsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense to me

@yash-atreya yash-atreya merged commit f21cbb5 into master Aug 25, 2025
22 checks passed
@yash-atreya yash-atreya deleted the yash/fix-contract-null-in-state-diff branch August 25, 2025 12:16
@github-project-automation github-project-automation bot moved this from Ready For Review to Done in Foundry Aug 25, 2025
@grandizzy grandizzy moved this from Done to Completed in Foundry Aug 25, 2025
MerkleBoy pushed a commit to MerkleBoy/foundry that referenced this pull request Sep 17, 2025
…#11404)

* fix(cheatcodes): identify proxies in state diffs

* dedup get_contract_name and get_contract_data

* clippy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-cheatcodes Area: cheatcodes C-forge Command: forge T-bug Type: bug
Projects
Status: Completed
Development

Successfully merging this pull request may close these issues.

3 participants