`deal` does not work on Aave's aTokens or other tokens that perform computation in `balanceOf`
Component
forge-std
Have you ensured that all of these are up to date?
- [X] Foundry
- [X] Foundryup
What version of Foundry are you on?
forge 0.2.0 (4b720c2 2022-07-28T00:04:25.986568Z)
What command(s) is the bug in?
forge test
Operating System
macOS (Intel)
Describe the bug
I have not been able to call deal on Aave's aToken (address: 0xBcca60bB61934080951369a648Fb03DF4F96263C). I have shared the stacktrace for the deal call below.
This happens in a test where the first line of the function is deal(token, msg.sender, amount);. The error message is [FAIL. Reason: stdStorage find(StdStorage): Slot(s) not found.].
In addition, it appears that aTokens are ERC20 compliant (their website states that aTokens support basic EIP20 functions).
Stack trace:
├─ [23586] InitializableImmutableAdminUpgradeabilityProxy::balanceOf(0x00a329c0648769a73afac7f9381e08fb43dbea72)
│ ├─ [18475] AToken::balanceOf(0x00a329c0648769a73afac7f9381e08fb43dbea72) [delegatecall]
│ │ ├─ [12856] InitializableImmutableAdminUpgradeabilityProxy::getReserveNormalizedIncome(0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) [staticcall]
│ │ │ ├─ [7745] LendingPool::getReserveNormalizedIncome(0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) [delegatecall]
│ │ │ │ └─ ← 1076877460561699683403779143
│ │ │ └─ ← 1076877460561699683403779143
│ │ └─ ← 0
│ └─ ← 0
├─ [0] VM::record()
│ └─ ← ()
├─ [4086] InitializableImmutableAdminUpgradeabilityProxy::balanceOf(0x00a329c0648769a73afac7f9381e08fb43dbea72) [staticcall]
│ ├─ [3475] AToken::balanceOf(0x00a329c0648769a73afac7f9381e08fb43dbea72) [delegatecall]
│ │ ├─ [2356] InitializableImmutableAdminUpgradeabilityProxy::getReserveNormalizedIncome(0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) [staticcall]
│ │ │ ├─ [1745] LendingPool::getReserveNormalizedIncome(0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) [delegatecall]
│ │ │ │ └─ ← 1076877460561699683403779143
│ │ │ └─ ← 1076877460561699683403779143
│ │ └─ ← 0
│ └─ ← 0
├─ [0] VM::accesses(InitializableImmutableAdminUpgradeabilityProxy: [0xbcca60bb61934080951369a648fb03df4f96263c])
│ └─ ← [0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, 0x7db14a3e80dc3d3973ac59ab9dd6e51be0941d8302f988ebabbd9d9f72c15b36], []
├─ [0] VM::load(InitializableImmutableAdminUpgradeabilityProxy: [0xbcca60bb61934080951369a648fb03df4f96263c], 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)
│ └─ ← 0x0000000000000000000000001c050bca8babe53ef769d0d2e411f556e1a27e7b
├─ [0] VM::store(InitializableImmutableAdminUpgradeabilityProxy: [0xbcca60bb61934080951369a648fb03df4f96263c], 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, 0x1337000000000000000000000000000000000000000000000000000000000000)
│ └─ ← ()
├─ [3108] InitializableImmutableAdminUpgradeabilityProxy::balanceOf(0x00a329c0648769a73afac7f9381e08fb43dbea72) [staticcall]
│ ├─ [0] 0x0000…0000::balanceOf(0x00a329c0648769a73afac7f9381e08fb43dbea72) [delegatecall]
│ │ └─ ← ()
│ └─ ← ()
├─ [0] VM::store(InitializableImmutableAdminUpgradeabilityProxy: [0xbcca60bb61934080951369a648fb03df4f96263c], 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, 0x0000000000000000000000001c050bca8babe53ef769d0d2e411f556e1a27e7b)
│ └─ ← ()
├─ [0] VM::load(InitializableImmutableAdminUpgradeabilityProxy: [0xbcca60bb61934080951369a648fb03df4f96263c], 0x7db14a3e80dc3d3973ac59ab9dd6e51be0941d8302f988ebabbd9d9f72c15b36)
│ └─ ← 0x0000000000000000000000000000000000000000000000000000000000000000
├─ emit WARNING_UninitedSlot(who: InitializableImmutableAdminUpgradeabilityProxy: [0xbcca60bb61934080951369a648fb03df4f96263c], slot: 56852350417691002906141485739722008029934276939945103568888814915257509174070)
├─ [0] VM::store(InitializableImmutableAdminUpgradeabilityProxy: [0xbcca60bb61934080951369a648fb03df4f96263c], 0x7db14a3e80dc3d3973ac59ab9dd6e51be0941d8302f988ebabbd9d9f72c15b36, 0x1337000000000000000000000000000000000000000000000000000000000000)
│ └─ ← ()
├─ [4535] InitializableImmutableAdminUpgradeabilityProxy::balanceOf(0x00a329c0648769a73afac7f9381e08fb43dbea72) [staticcall]
│ ├─ [3911] AToken::balanceOf(0x00a329c0648769a73afac7f9381e08fb43dbea72) [delegatecall]
│ │ ├─ [2356] InitializableImmutableAdminUpgradeabilityProxy::getReserveNormalizedIncome(0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) [staticcall]
│ │ │ ├─ [1745] LendingPool::getReserveNormalizedIncome(0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) [delegatecall]
│ │ │ │ └─ ← 1076877460561699683403779143
│ │ │ └─ ← 1076877460561699683403779143
│ │ └─ ← "48"
│ └─ ← "48"
├─ [0] VM::store(InitializableImmutableAdminUpgradeabilityProxy: [0xbcca60bb61934080951369a648fb03df4f96263c], 0x7db14a3e80dc3d3973ac59ab9dd6e51be0941d8302f988ebabbd9d9f72c15b36, 0x0000000000000000000000000000000000000000000000000000000000000000)
│ └─ ← ()
└─ ← "stdStorage find(StdStorage): Slot(s) not found."
it's because they do math on the stored value and it returns an overflow error. We should change the default value for deal to 1337 instead of 0x13370000..000, and that should fix it.

Tried looking into this actually. Changing it from bytes32(hex"1337") to bytes32(uint256(1337)) will get it further in the code but it will still fail on this check. Also tried it against your storage PR where it failed at the same spot. Will continue looking into stdStorage but thought I'd make you aware.
Not sure if this will help anyone, but to shed some light on this:
While the aToken follows erc20 it's implemented slightly different internally - balances is a mapping of struct, so not uint256, but (uint128,uint128), where first is balance, second it index.
To deal someone e.g. x aDAI there's infinite possibilities to represent this with the struct, by choosing index + balance wisely in relation to the current index.
Probably the most reasonable way would be to:
- fetch the current index
ifrom the attached pool - scale
xdown by i asyand write storage asy,i
Checked the code a bit though, and not sure how reasonable it would be to have such a special case for aTokens :sweat_smile:
Also using this issue to track other tokens this has been reported for:
- OUSD: https://github.com/foundry-rs/foundry/issues/4595
- DIGG: https://github.com/foundry-rs/forge-std/issues/444