DatingDapp

AI First Flight #6
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: low
Likelihood: low
Invalid

Liked event omits the ETH amount paid, breaking off-chain reconstruction of stake history

Description

likeUser() emits Liked(msg.sender, liked) but never includes msg.value.
Any off-chain consumer that relies on event logs rather than re-fetching
raw transaction data (subgraphs, indexers, the project's own frontend)
cannot determine how much was staked on a given like from the emitted
event alone.

Root Cause


event Liked(address indexed liker, address indexed liked);
​
function likeUser(address liked) external payable {
require(msg.value >= 1 ether, "Must send at least 1 ETH");
...
likes[msg.sender][liked] = true;
@> emit Liked(msg.sender, liked); // msg.value paid is not part of the event
...
}

Risk

Likelihood:

  • Every call to likeUser() emits this event without the paid amount — unconditional, not an edge case.

Impact:

  • Standard indexing frameworks (e.g. TheGraph) build entirely off emitted event data and do not re-fetch per-transaction msg.value — so stake history, per-user spend totals, or any analytics built purely on logs cannot be reconstructed without an expensive, non-standard fallback to raw tx data.

  • Worth flagging honestly: with the Finding #1 fix (== 1 ether fixed price), the practical severity is mild right now, since the amount is currently always constant and technically inferable. The real issue is design coupling — any indexer that hardcodes "value is always 1 ether" silently breaks the moment this contract is redeployed or upgraded with a different price. Events should carry the actual economic data rather than depend on an assumption about contract logic elsewhere. This is why it's Informational, not Low.

Proof of Concept

function test_LikedEvent_DoesNotEmitValue() public {
vm.expectEmit(true, true, false, true);
emit LikeRegistry.Liked(alice, bob); // no way to assert a value= field — it isn't there
​
vm.prank(alice);
likeRegistry.likeUser{value: 1 ether}(bob);
// An indexer parsing this event sees liker/liked only — the 1 ETH
// paid is recoverable only by separately fetching the transaction.
}

Recommended Mitigation


- event Liked(address indexed liker, address indexed liked);
+ event Liked(address indexed liker, address indexed liked, uint256 amount);
​
function likeUser(address liked) external payable {
require(msg.value == 1 ether, "Must send exactly 1 ETH");
...
likes[msg.sender][liked] = true;
+ likeStakes[msg.sender][liked] = msg.value;
- emit Liked(msg.sender, liked);
+ emit Liked(msg.sender, liked, msg.value);
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 1 hour ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!