Testing emits
Ref - https://book.getfoundry.sh/forge/cheatcodes
The ERC-20 contract emits events whenever a transfer/approval happens.
Emits
In Solidity, emits refers to the action of emitting an event. Events are a fundamental feature of the Ethereum smart contract system, allowing contracts to log important data that can be observed externally.
// Declaring an eventevent Transfer(address indexed from, address indexed to, uint256 value);
// Emitting an eventemit Transfer(msg.sender, recipient, 100);
This is how they’re stored on the blockchain
Event Log:- Topics: - from: 0x1234567890abcdef (address of the sender) - to: 0xfedcba0987654321 (address of the recipient)- Data: - value: 1000 (value transferred in the transaction)
Indexed Parameters in Events
https://etherscan.io/tx/0x046c2609f21f3308d8f7f902a51ac14f86b9e6b9f54ab1b4f269575d09bc93e5#eventlog
Indexed parameters
In Solidity, events allow you to mark some of the parameters as indexed. Indexed parameters make the event log searchable, as they allow external listeners (like DApps or off-chain services) to filter events by those parameters more efficiently.
The EVM allows you to index up to 3 parameters per event.
Testing emits
// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.13;
import {Test, console} from "forge-std/Test.sol";import { MyToken } from "../src/Token.sol";
contract CounterTest is Test { MyToken public token; event Transfer(address indexed from, address indexed to, uint256 amount);
function setUp() public { token = new MyToken(); }
function test_ExpectEmit() public { token.mint(address(this), 100); // Check that topic 1, topic 2, and data are the same as the following emitted event. // Checking topic 3 here doesn't matter, because `Transfer` only has 2 indexed topics. vm.expectEmit(true, true, false, true); // The event we expect emit Transfer(address(this), 0x075c299cf3b9FCF7C9fD5272cd2ed21A4688bEeD, 100); // The event we get token.transfer(0x075c299cf3b9FCF7C9fD5272cd2ed21A4688bEeD, 100); }
function test_ExpectEmitApprove() public { token.mint(address(this), 100);
vm.expectEmit(true, true, false, true); emit Approval(address(this), 0x075c299cf3b9FCF7C9fD5272cd2ed21A4688bEeD, 100);
token.approve(0x075c299cf3b9FCF7C9fD5272cd2ed21A4688bEeD, 100); vm.prank(0x075c299cf3b9FCF7C9fD5272cd2ed21A4688bEeD); token.transferFrom(address(this), 0x075c299cf3b9FCF7C9fD5272cd2ed21A4688bEeD, 100); }}