Ethereum: Issue with tx.origin and msg.sender in Foundry test

Ethereum: Issue with tx.origin and msg.sender in Foundry testing

As part of my ongoing research on smart contracts, I have been working on a test case for an Ethernaut Level 4 (phone) contract using Foundry. However, an unexpected issue has arisen that requires troubleshooting.

Issue:

During testing, I noticed that the tx.origin and msg.sender fields in my contract were not working as expected. In particular, these fields seemed to return different values ​​than I expected.

Topic:

After looking at the contract code and understanding how it works with the blockchain, I realized there are two main issues here:

  • tx.origin: The tx.origin field contains the address of the account that initiated the transaction (i.e. the sender). However, when using the Foundry testing framework, this value is not always accurate.
  • msg.sender: The msg.sender field contains the address of the account that called the contract function (i.e. the recipient). This value may be different from tx.origin, especially if the transaction was sent via a different account.

Solution:

To solve this problem, I made several changes to my test code:

  • Use the sender attribute instead of origin

    : In the Foundry test framework, sender seems to be the correct attribute to use in conjunction with the event sender.

  • Use contractAddress as a fallback: If tx.origin and msg.sender are still different, I can fallback to the contract address (“contractAddress”) as an alternative.

Here is an updated code snippet demonstrating these changes:

const { Ether } = require("Ether");

// Test case for phone contract

asynchronous function testTelephone() {

// Initialize contract and account

const phoneContract = new Ether.Contract(

"

PhoneContract ABI,

ethers.Wallet.fromPrivateKey(

"YOUR_PRIVATE_KEY", // Replace it with your private key

)

);

//Create an event object

Constants tx = {

Sender: ethers.Wallet.fromPrivateKey("YOUR_PRIVATE_KEY"),

Recipient: phoneContract.address, // The correct address for this contract

Value: ethers.utils.parseEther("1"), // Set the event value

gasPrice: 20n, // Set gas price (optional)

gasLimit: 2000, // Set maximum gas limit

data: "0x", // Sets the event data (empty in this case)

};

// Run the event

const result = wait for phoneContract.sendTransaction(tx);

console.log(result);

}

// Run the test function

testPhone();

Conclusion:

Applying these changes helped me resolve the issue with tx.origin and msg.sender in my phone contract test case. Now that the values ​​are accurate, I can continue testing and analyzing.

If you have similar issues or have any questions about this solution, feel free to ask!