Echo: Gensyn Token Sale
Cantina Security Report
Organization
- @echo
Engagement Type
Cantina Reviews
Period
-
Researchers
Findings
Low Risk
1 findings
0 fixed
1 acknowledged
Informational
3 findings
3 fixed
0 acknowledged
Low Risk1 finding
recoverTokens allows to withdraw commitment tokens
State
- Acknowledged
Severity
- Severity: Low
≈
Likelihood: Low×
Impact: Low Submitted by
rvierdiiev
Description
Currently the
recoverTokens()function does not restrict which tokens can be recovered. As a result, an account with theTOKEN_RECOVERER_ROLEcan withdraw USDT and USDC, which are the core commitment tokens used by the protocol.Recommendation
Add validation ensuring that commitment tokens (e.g., USDT and USDC) cannot be recovered through
recoverTokens(). Only non-core, mistakenly sent tokens should be recoverable by theTOKEN_RECOVERER_ROLE.
Informational3 findings
Remove redundant errors
State
- Fixed
PR #2
Severity
- Severity: Informational
≈
Likelihood: Low×
Impact: Low Submitted by
rvierdiiev
Description
error ZeroPrice();error MaxAddressesPerEntityExceededThose errors are never used in the code base.
Recommendation
Remove redundant errors.
Differences between comments and the code
State
- Fixed
PR #2
Severity
- Severity: Informational
≈
Likelihood: Low×
Impact: Low Submitted by
rvierdiiev
Description
According to the comments:
Bids must satisfy monotonic constraints: amounts and prices can only increase, and lockup preferences can be enabled but cannot be disabled once set.
However, the implementation only enforces that the new bid's amount and price are not lower than the previous bid. This means a user can submit a bid where both the amount and price are exactly the same as the previous one.
Recommendation
Require both amount and price to be strictly greater than the previous bid’s values.
EIP-2612 permit signatures can be front-run for replaceBidWithPermit
Description
An adversary can extract permit signature from mempool and front-run to submit directly to ERC-20 contract, so
pToken.permitwould revert later when original transaction lands with same permit sig.however, since there is
replaceBidWithApprovalis present, this doesn't lead to complete DOS.Recommendation
- add a
try / catcharoundpermit, so that even if permit reverts, it can be ignored and proceed with transfering - frontend must ensure
replaceBidWithApprovalis used as fallback ifreplaceBidWithPermitkeeps reverting
- add a