Indexed keyword use case

I have been using indexed keyword for my events .

The official definition for this keyword is to filter the info in the log , and it is the cost efficient way to use this inside event . But it will cost more on transaction mining side . So we need a balance for this.

In terms of the following event , which param should i mark as indexed , and why ?

event LogRewardPaidByPool(
uint256 assetId,
address user,
uint256 indexed amount
);

event LogRewardPoolAdded(
    uint256 assetId,
    uint256 phase,
    uint256 allocPoint
);

event LogUpdatePoolRewards(
    uint256 assetId,
    uint256 lastRewardTime,
    uint256 globalPoolBalance,
    uint256 accRewardPerShare
);

According to the documentation: You can add the attribute indexed to up to three parameters which adds them to a special data structure known as “topics” instead of the data part of the log.

All parameters without the indexed attribute are ABI-encoded into the data part of the log.

So, in short you can use indexed parameter to filter event logs, normally you indexed addresses since is the best option when it comes to searches, but it all comes down to your specific use case.

In your events I would index the following on each:

event LogRewardPaidByPool(
uint256 assetId,
address indexed user,
uint256 amount
);

event LogRewardPoolAdded(
    uint256 indexed assetId,
    uint256 phase,
    uint256 allocPoint
);

event LogUpdatePoolRewards(
    uint256 indexed assetId,
    uint256 lastRewardTime,
    uint256 globalPoolBalance,
    uint256 accRewardPerShare
);

Because I think the most likely searches will be for the assetID and the user, but you might consider others to be more important.

Thanks , i am actually thinking about the same , it just hard to choose from

The problem or the balance that we want to achieve here is

we might have to index the reward amount paid to the user in the LogRewardPaid event,
but if we do that, we might also want to index the assetId since that denotes the reward pool for. which the reward was paid to the user, and also the user...

so in the end, we might end up indexing all the params in an event like this ,
which would be highly costly..

Any insight on this ?

You can get the rest of the data from the event log once you filter it by the indexed parameter, therefore is not like you need to index everything you are going to use, but rather index only what will be useful to get the correct event, and have a separate logic in your code to read the event log parameters (the not indexed ones)

Looks reasonable , but would you like to give a specific instance on how doing so ?

Using ethers it would be, and taking LogRewardPaid as an example, getting the arguments would be:

const tx = await instance.foo1();
const result = await tx.wait();
const event = result.events.filter((x: { event: string; }) => x.event == "LogRewardPaidByPool").pop();//filter by event name
console.log("All arguments", event.args);```

Thanks for the continued support !
It is really helpful , openzeppelin mate !

Julissa Dantes-Castillo via OpenZeppelin Forum <notifications@zeppelin.discoursemail.com> 于2023年1月25日周三 05:43写道: