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

Ethereum: Issue with tx.origin и msg.sender in Foundry Test

As part of my ongoing research into smart contracts, I was working on a test case for the Ethernaut Level-4 (Telephone) contract using Foundry. However, I encountered an unexpected issue that required some troubleshooting.

The Problem:

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

During testing, I noticed that the tx.origin и msg.sender fields in my contract were not behaving as expected. Specifically, these fields seemed to be providing different values than I was expecting.

The Issue:

After reviewing the contract code and understanding how it interacts with the blockchain, I realized that there are two main issues at play here:

  • tx.origin: The tx.origin field contains the address of the account that initiated the transaction (i.e., the sender). However, when using Foundry’s 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 can be different from tx.origin, especially if the transaction was sent via a different account.

The Solution:

To resolve this issue, I applied several modifications to my test code:

  • Use sender instead of origin: In Foundry’s testing framework, it seems that sender is the correct attribute to use when accessing the sender of a transaction.

  • Use contractAddress as a fallback

    : If tx.origin и msg.sender are still different, I can fall back to using the contract address (contractAddress) as an alternative.

Here’s an updated code snippet demonstrating these changes:

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

// Test case for Telephone contract

async function testTelephone() {

// Initialize contract and account

const telephoneContract = new ethers.Contract(

"

telephoneContract ABI,

ethers.Wallet.fromPrivateKey(

"YOUR_PRIVATE_KEY", // Replace with your private key

)

);

// Create a transaction object

const tx = {

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

to: telephoneContract.address, // Correct address for this contract

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

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

gasLimit: 2000, // Set the maximum gas limit

data: "0x", // Set the transaction data (empty in this case)

};

// Perform the transaction

const result = await telephoneContract.sendTransaction(tx);

console.log(result);

}

// Run the test function

testTelephone();

Conclusion:

By applying these modifications, I was able to resolve the issue with tx.origin и msg.sender in my test case for the Telephone contract. Now that the values are accurate, I can proceed with further testing and analysis.

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