Curves protocol introduces external token feature, allowing ERC20 compatibility for shares, which FriendTech lacks.
External ERC20 is deployed once per subject from _deployERC20, either in the same transaction when the first share is created (buyCurvesTokenWithName), or later, when someone actually needs ERC20 (withdraw or mint).
The _deployERC20 function contains a conditional revert, that can be exploited to prevent all users from using ERC20's completely.
DoS of withdraw and mint
withdraw and mint call _deployERC20 with default name and symbol.
As long as _deployERC20 is called with default name and symbol, it will deploy tokens with symbols "CURVES1", "CURVES2", etc.
When _curvesTokenCounter == X-1, if someone calls buyCurvesTokenWithName(symbol = "CURVESX"), _curvesTokenCounter will not be incremented, but symbolToSubject["CURVESX"] will be set to true.
After that, every time someone mints or withdraws a token that does not have an externalToken, the check
if (symbolToSubject[symbol] != address(0)) revert InvalidERC20Metadata();
will revert. Therefore, all existing and future collections that were not created via buyCurvesTokenWithName will never be able to have external ERC20 representation.
Attack steps
Adversary retrieves _curvesTokenCounter value from the Curves contract (e.g. via web3.js)
Adversary calls buyCurvesTokenWithName(symbol = "CURVESX"), where X = _curvesTokenCounter + 1
DoS of buyCurvesTokenWithName
To DoS future subjects that would use buyCurvesTokenWithName, a more demanding solution will be needed:
Each time someone is submitting buyCurvesTokenWithName transaction, the attacker will need to frontrun it with the same symbol, and repeat it for every new attempt. However, the fees on Form network are extremely cheap, so it may be feasible for someone to set up such griefing bot.
Attack steps
Alice submits buyCurvesTokenWithName(symbol = "ALICE")
Malicious Bob frontruns her with buyCurvesTokenWithName(symbol = "ALICE")
Alice's transaction reverts. Whenever she tries a different symbol, Bob will frontrun her with this symbol.
External ERC20 can not be deployed for any subject.
Recommended Mitigation Steps
Either remove buyCurvesTokenWithName, or allow multiple tokens to have the same symbol by removing symbolToSubject mapping and the conditional revert().
Lines of code
https://github.com/code-423n4/2024-01-curves/blob/516aedb7b9a8d341d0d2666c23780d2bd8a9a600/contracts/Curves.sol#L338-L350
Vulnerability details
Vulnerability Details
Curves protocol introduces external token feature, allowing ERC20 compatibility for shares, which FriendTech lacks.
External ERC20 is deployed once per subject from
_deployERC20
, either in the same transaction when the first share is created (buyCurvesTokenWithName
), or later, when someone actually needs ERC20 (withdraw
ormint
).The
_deployERC20
function contains a conditional revert, that can be exploited to prevent all users from using ERC20's completely.DoS of
withdraw
andmint
withdraw
andmint
call_deployERC20
with default name and symbol.As long as
_deployERC20
is called with default name and symbol, it will deploy tokens with symbols "CURVES1", "CURVES2", etc.When
_curvesTokenCounter == X-1
, if someone callsbuyCurvesTokenWithName(symbol = "CURVESX")
,_curvesTokenCounter
will not be incremented, butsymbolToSubject["CURVESX"]
will be set totrue
.After that, every time someone
mint
s orwithdraw
s a token that does not have anexternalToken
, the checkwill revert. Therefore, all existing and future collections that were not created via
buyCurvesTokenWithName
will never be able to have external ERC20 representation.Attack steps
_curvesTokenCounter
value from the Curves contract (e.g. via web3.js)buyCurvesTokenWithName(symbol = "CURVESX")
, whereX = _curvesTokenCounter + 1
DoS of
buyCurvesTokenWithName
To DoS future subjects that would use
buyCurvesTokenWithName
, a more demanding solution will be needed:Each time someone is submitting
buyCurvesTokenWithName
transaction, the attacker will need to frontrun it with the same symbol, and repeat it for every new attempt. However, the fees on Form network are extremely cheap, so it may be feasible for someone to set up such griefing bot.Attack steps
buyCurvesTokenWithName(symbol = "ALICE")
buyCurvesTokenWithName(symbol = "ALICE")
Proof of Concept
Foundry PoC
Adding Foundry to Hardhat
Impact
External ERC20 can not be deployed for any subject.
Recommended Mitigation Steps
Either remove
buyCurvesTokenWithName
, or allow multiple tokens to have the same symbol by removingsymbolToSubject
mapping and the conditionalrevert()
.Assessed type
DoS