Closed AAYUSH-GUPTA-coder closed 3 months ago
The USDB token dynamically calculates balance as you can see here: https://blastscan.io/address/0x4ef0d788470e2feb6559b93075ec5be51dba737d#code%23F4%23L107
Therefore, there is no single slot to directly write to for updating a user's balance, which is why it fails. See https://github.com/foundry-rs/forge-std/issues/140#issuecomment-1697429178 for other examples of tokens with this issue
You will need to understand how the USDB token returns balances and determine what values to write to what slots. Alternatively, you can use vm.mockCall
to mock the value returned from balanceOf
calls
Thank you @mds1 for your guidance. I've successfully solved this problem using vm.mockCall()
.
For anyone facing a similar issue, here's a comprehensive solution:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import "forge-std/Test.sol";
import "forge-std/console.sol";
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
}
contract TestERC20RebasingToken is Test {
IERC20 public usbd;
// address of usdb token
address public usdbAddr = 0x4300000000000000000000000000000000000003;
function setUp() public {
usbd = IERC20(usdbAddr);
}
function testMockTokenBalance() public {
address user = address(2);
// The balance we want to set
uint256 mockBalance = 1000 * 1e18; // 1000 tokens with 18 decimals
// 1. Get the function signature for balanceOf
bytes4 balanceOfSelector = IERC20.balanceOf.selector;
// 2. Encode the parameters (in this case, just the user address)
bytes memory balanceOfData = abi.encodeWithSelector(
balanceOfSelector,
user
);
// 3. Encode the return data (the balance)
bytes memory returnData = abi.encode(mockBalance);
// 4. Mock the call
vm.mockCall(usdbAddr, balanceOfData, returnData);
// 5. Now when we call balanceOf, it should return our mocked balance
uint256 balance = IERC20(usdbAddr).balanceOf(user);
// 6. Assert that the balance is what we set
assertEq(balance, mockBalance, "Balance should be mocked value");
console.log("Balance of usdb of user", usbd.balanceOf(user));
}
}
Foundry Doc link : mockCall()
Description
I am working with the BLAST Blockchain in a Foundry testing environment, specifically using a mainnet fork for testing. My goal is to set the USDB (a stablecoin with 18 decimals) balance for a user account during the testing process.
Error Encountered
When executing the following line in my Foundry test:
I receive the following error:
Foundry Test Code
Additional Context
user
account to 1 USDB (1 * 10^18 due to 18 decimals) using thedeal
function.usdbAddr
is the contract address of the USDB stablecoin on the BLAST Blockchain.user
account is being set to the labeled addressaddress(2)
for testing purposes.Expected Behavior
The
deal
function should successfully set the USDB balance of theuser
account to 1 USDB (1 * 10^18) without encountering any errors.Actual Behavior
The
deal
function fails with the error[FAIL. Reason: revert: stdStorage find(StdStorage): Failed to write value.]
, indicating that the test environment is unable to write the USDB balance to theuser
account.Please provide guidance on how to resolve this issue and successfully set the USDB balance for the
user
account during testing in the Foundry mainnet fork environment.