Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GraphToken permit() function is vulnerable to approval double spending : #293

Open
code423n4 opened this issue Oct 12, 2022 · 3 comments
Open
Labels
bug Something isn't working QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2022-10-thegraph/blob/309a188f7215fa42c745b136357702400f91b4ff/contracts/l2/token/GraphTokenUpgradeable.sol#L98

Vulnerability details

Description

GraphTokenUpgradeable exports a standard permit() function. If the signature checks out, it calls _approve(_owner, _spender, _value);This is vulnerable to a well known issue where spender of the permit can now spend previous allowance + _value, instead of just _value token. He does this by frontrunning the permit() function and spending the existing approved funds.

Impact

Spender of permit may double spend user's allowance.

Proof of Concept

Alice approves Bob access to 100 Graph tokens. After thinking about it, she wants to give Bob approval for 50 more tokens. She signs a permit for 150 Graph tokens. Seeing the Permit TX in the mempool, Bob frontruns it and spends his 100 Graph tokens. Therefore, he received access to 250 total tokens.

Tools Used

Manual audit

Recommended Mitigation Steps

Permit should only be allowed to toggle between zero and non zero allowance.

Note to judges: a very similar finding appeared in Olympus  where HIGH was awarded.

@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Oct 12, 2022
code423n4 added a commit that referenced this issue Oct 12, 2022
@0xean
Copy link
Collaborator

0xean commented Oct 14, 2022

Downgrading to QA. After discussing this issue with a few judges have significantly revised how I think about this attack vector in general.

@0xean 0xean added QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax and removed 3 (High Risk) Assets can be stolen/lost/compromised directly labels Oct 14, 2022
@pcarranzav
Copy link

Alice approves Bob access to 100 Graph tokens. After thinking about it, she wants to give Bob approval for 50 more tokens. She signs a permit for 150 Graph tokens. Seeing the Permit TX in the mempool, Bob frontruns it and spends his 100 Graph tokens. Therefore, he received access to 250 total tokens.

I would argue that if Alice wants this she should either:

a) Sign the permit for 150 GRT using the same nonce, invalidating the permit for 100, or
b) Sign a separate permit for 50 GRT

@pcarranzav pcarranzav added the sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue label Oct 18, 2022
@pcarranzav
Copy link

^ To be clear, based on my argument above, I would recommend marking as invalid rather than QA; I believe the described attack vector would work for someone calling GraphToken.approve (as with any ERC20 token, and I think those are the attacks described in Olympus and code-423n4/org#51), but the described POC requires the approver to make an incorrect use of nonces or the permit feature. By design, a user can sign multiple permits with different amounts, and they will be valid if they are redeemed in the correct order based on their nonces, until the deadline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue
Projects
None yet
Development

No branches or pull requests

3 participants