foundry: Bug: `cast storage` displays wrong values for packed slots

Component

Cast

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (64b0e8f 2023-11-15T14:06:05.905353479Z)

What command(s) is the bug in?

cast storage

Operating System

Linux

Describe the bug

Repro example (replace it with your Etherscan API key of Optimism).

Run:

cast storage --rpc-url https://mainnet.optimism.io --etherscan-api-key <YOUR_API_KEY> 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2

which returns:

| Name    | Type    | Slot | Offset | Bytes | Value                                            | Contract
                       |
|---------|---------|------|--------|-------|--------------------------------------------------|-----------------------------------------------|
| _owner  | address | 0    | 0      | 20    | 486747459873938072359747357390379788195179410093 | contracts/Create2Deployer.sol:Create2Deployer |
| _paused | bool    | 0    | 20     | 1     | 486747459873938072359747357390379788195179410093 | contracts/Create2Deployer.sol:Create2Deployer |

The value of _paused is set to the _owner value, which however should be simply 0 in this case.

About this issue

  • Original URL
  • State: closed
  • Created 8 months ago
  • Comments: 19 (19 by maintainers)

Commits related to this issue

Most upvoted comments

The https://github.com/foundry-rs/foundry/pull/6370 PR mentions further downstream improvements in a PR. Adding an example for bool offset calculating values as not 0 or 1

reproduce:

cast storage --rpc-url https://mainnet.optimism.io --etherscan-api-key T2KRFNUMEN4U8XZQ87YCN82I3AF6XE21NF 0xB67c152E69217b5aCB85A2e19dF13423351b0E27

what:

  • isUserCancelEnabled is a bool and is 256
  • allowUserCloseOnly is a bool and is 16777216
| Name                          | Type                                                            | Slot | Offset | Bytes | Value                                             | Hex Value                                                          | Contract                                           |
|-------------------------------|-----------------------------------------------------------------|------|--------|-------|---------------------------------------------------|--------------------------------------------------------------------|----------------------------------------------------|
| gov                           | address                                                         | 0    | 0      | 20    | 1352965747418285184211909460723571462248744342032 | 0x000000000000000000000000ecfd15165d994c2766fbe0d6bacdc2e8dedfd210 | contracts/perp/PositionManager.sol:PositionManager |
| _status                       | uint256                                                         | 1    | 0      | 32    | 1                                                 | 0x0000000000000000000000000000000000000000000000000000000000000001 | contracts/perp/PositionManager.sol:PositionManager |
| admin                         | address                                                         | 2    | 0      | 20    | 1352965747418285184211909460723571462248744342032 | 0x000000000000000000000000ecfd15165d994c2766fbe0d6bacdc2e8dedfd210 | contracts/perp/PositionManager.sol:PositionManager |
| feeCalculator                 | address                                                         | 3    | 0      | 20    | 1297482016264593221714872710065075000476194625473 | 0x000000000000000000000000e3451b170806aab3e24b5cd03a331c1ccdb4d7c1 | contracts/perp/PositionManager.sol:PositionManager |
| oracle                        | address                                                         | 4    | 0      | 20    | 241116142622541106669066767052022920958068430970  | 0x0000000000000000000000002a3c0592dcb58accd346ccee2bb46e3fb744987a | contracts/perp/PositionManager.sol:PositionManager |
| referralStorage               | address                                                         | 5    | 0      | 20    | 1224602325975115131568536406232630666650384091454 | 0x000000000000000000000000d6811146780d50d24bd3475acb23c2118034493e | contracts/perp/PositionManager.sol:PositionManager |
| minExecutionFee               | uint256                                                         | 6    | 0      | 32    | 20000                                             | 0x0000000000000000000000000000000000000000000000000000000000004e20 | contracts/perp/PositionManager.sol:PositionManager |
| minBlockDelayKeeper           | uint256                                                         | 7    | 0      | 32    | 0                                                 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/perp/PositionManager.sol:PositionManager |
| minTimeExecuteDelayPublic     | uint256                                                         | 8    | 0      | 32    | 180                                               | 0x00000000000000000000000000000000000000000000000000000000000000b4 | contracts/perp/PositionManager.sol:PositionManager |
| minTimeCancelDelayPublic      | uint256                                                         | 9    | 0      | 32    | 180                                               | 0x00000000000000000000000000000000000000000000000000000000000000b4 | contracts/perp/PositionManager.sol:PositionManager |
| maxTimeDelay                  | uint256                                                         | 10   | 0      | 32    | 1800                                              | 0x0000000000000000000000000000000000000000000000000000000000000708 | contracts/perp/PositionManager.sol:PositionManager |
| isUserExecuteEnabled          | bool                                                            | 11   | 0      | 1     | 1                                                 | 0x0000000000000000000000000000000000000000000000000000000000000001 | contracts/perp/PositionManager.sol:PositionManager |
| isUserCancelEnabled           | bool                                                            | 11   | 1      | 1     | 256                                               | 0x0000000000000000000000000000000000000000000000000000000000000100 | contracts/perp/PositionManager.sol:PositionManager |
| allowPublicKeeper             | bool                                                            | 11   | 2      | 1     | 0                                                 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/perp/PositionManager.sol:PositionManager |
| allowUserCloseOnly            | bool                                                            | 11   | 3      | 1     | 16777216                                          | 0x0000000000000000000000000000000000000000000000000000000001000000 | contracts/perp/PositionManager.sol:PositionManager |
| openPositionRequestKeys       | bytes32[]                                                       | 12   | 0      | 32    | 27359                                             | 0x0000000000000000000000000000000000000000000000000000000000006adf | contracts/perp/PositionManager.sol:PositionManager |
| closePositionRequestKeys      | bytes32[]                                                       | 13   | 0      | 32    | 16981                                             | 0x0000000000000000000000000000000000000000000000000000000000004255 | contracts/perp/PositionManager.sol:PositionManager |
| openPositionRequestKeysStart  | uint256                                                         | 14   | 0      | 32    | 27359                                             | 0x0000000000000000000000000000000000000000000000000000000000006adf | contracts/perp/PositionManager.sol:PositionManager |
| closePositionRequestKeysStart | uint256                                                         | 15   | 0      | 32    | 16981                                             | 0x0000000000000000000000000000000000000000000000000000000000004255 | contracts/perp/PositionManager.sol:PositionManager |
| isPositionKeeper              | mapping(address => bool)                                        | 16   | 0      | 32    | 0                                                 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/perp/PositionManager.sol:PositionManager |
| openPositionsIndex            | mapping(address => uint256)                                     | 17   | 0      | 32    | 0                                                 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/perp/PositionManager.sol:PositionManager |
| openPositionRequests          | mapping(bytes32 => struct PositionManager.OpenPositionRequest)  | 18   | 0      | 32    | 0                                                 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/perp/PositionManager.sol:PositionManager |
| closePositionsIndex           | mapping(address => uint256)                                     | 19   | 0      | 32    | 0                                                 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/perp/PositionManager.sol:PositionManager |
| closePositionRequests         | mapping(bytes32 => struct PositionManager.ClosePositionRequest) | 20   | 0      | 32    | 0                                                 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/perp/PositionManager.sol:PositionManager |
| managers                      | mapping(address => bool)                                        | 21   | 0      | 32    | 0                                                 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/perp/PositionManager.sol:PositionManager |
| approvedManagers              | mapping(address => mapping(address => bool))                    | 22   | 0      | 32    | 0                                                 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/perp/PositionManager.sol:PositionManager |

his should be straight forward, basically only including the relevant range of the get_storage_at response value determined by the offset

Happy to take this

reviewing asap, sorry forgot about it -.-