The _approve function uses inline assembly marked as memory-safe but fails to update the free memory pointer at 0x40 after allocating and using memory. This violates Solidity's memory safety model.
The function reads the free memory pointer (stored at 0x40) which tells it where safe memory starts, typically 0x80
It uses 64 bytes of memory (from 0x80 to 0xC0) for temporary calculations
Bug: It never updates the free memory pointer to 0xC0 after using the space
The next function that needs memory also reads the pointer at 0x40
It gets the same answer: 0x80 (not updated to 0xC0)
It writes to 0x80, overwriting data from the previous operation
This memory collision can corrupt calculations and cause unexpected transaction failures
Issue Arises when:
Multiple approve calls in one transaction
Approve followed by transfer in a multicall
Any contract that inherits this code and uses memory-intensive operations after `_approve` calls is at risk of memory corruption.
Memory Collision in Complex Transactions
Incorrect Storage Calculations (Edge Case)
This vulnerability is difficult to reproduce in Foundry , I have added the memory layout of before nad after approve.
Add mstore(0x40, add(ptr, 0x40)) before success := 1
This ensures the free memory pointer correctly points to 0xC0 (64 bytes past the initial pointer), marking memory 0x80-0xC0 as used.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.