Platform: Code4rena
Start Date: 24/02/2022
Pot Size: $75,000 USDC
Total HM: 21
Participants: 28
Period: 7 days
Judge: alcueca
Total Solo HM: 15
Id: 94
League: ETH
Rank: 8/28
Findings: 3
Award: $2,818.31
๐ Selected for report: 1
๐ Solo Findings: 1
๐ Selected for report: 0x1f8b
2434.7549 USDC - $2,434.75
Front running attack in approve.
The contract of the FETH
does not have any protection against the well-known โMultiple Withdrawal Attackโ attack on the Approve/TransferFrom methods of the ERC20 standard.
Although this attack poses a limited risk in specific situations, it is worth mentioning to consider it for possible future operations.
There are solutions to mitigate this front running such as, to first reduce the spender's allowance to 0 and set the desired value afterwards; another solution could the one that Open Zeppelin offers, where the non-standard decreaseAllowance and increaseAllowance functions have been added to mitigate the well-known issues involving setting allowances.
Add increase and decrease allowance.
#0 - HardlyDifficult
2022-03-07T12:03:01Z
Yes, this is a good best practice to be following. We will add these functions in the near future. In the meantime we've added an inline comment about the potential risk.
At first we don't expect there will be much interest in using FETH outside of Foundation itself. Thanks to the trusted relationship with the market contract, approvals are not necessary. So this is not an issue that should come up in the near term.
We are not fixing this immediately because it introduces a risk associated with another contract our users have deployed, that contract was not part of the contest repo. We are looking to patch that vulnerability and then will add increaseAllowance
to FETH.
๐ Selected for report: leastwood
Also found by: 0x1f8b, 0xliumin, 0xwags, CertoraInc, Dravee, IllIllI, Ruhum, TerrierLover, WatchPug, cmichel, csanuragjain, defsec, gzeon, hubble, jayjonah8, kenta, kirk-baird, rfa, robee
181.0202 USDC - $181.02
The signature used in requireAuthorizedAccountMigration
can be reused over different netoworks.
It's mandatory to add the chainId
to these kind of message before be signed, in order to be resilient to be used over different networks.
#0 - HardlyDifficult
2022-02-28T19:16:02Z
In a way, this is a feature not a bug. The use case for this signature is meant to be used only when the private key for their original account has been compromised. When that occurs, that account should never be used again regardless of the network. So when Foundation supports multiple chains, we would want the ability to migrate their account on all networks and it would be most convenient to do that with only 1 signature required from the user.
We acknowledge that including the chainId with signatures is generally a best practice, and may consider changing that in the future.
We believe this is a 1 (Low Risk)
issue because of the point above, but also the signature is only usable when broadcasted by a Foundation admin which should not be abusing the capability.
#1 - alcueca
2022-03-16T09:51:41Z
Including the chainId with signatures is a best practice, but only when the signature is supposed to be valid only on one network. In this case if the signature should be used across all networks, there is no need to restrict it.
However, the lack of natspec of other documentation describing this makes this a valid issue.
The fact that the feature can only be abused by a privileged account reduces its severity by one, to Sev 1.
#2 - alcueca
2022-03-17T10:00:13Z
QA Report score: 10
#3 - CloudEllie
2022-03-24T19:03:00Z
Since this issue was downgraded to a QA level, and the warden did not submit a separate QA report, we've renamed this one to "QA report" for consistency.
The original title, for the record, was "Signature reusable over different networks."
๐ Selected for report: Dravee
Also found by: 0x1f8b, CertoraInc, TerrierLover, csanuragjain, gzeon, iain, kenta, rfa, robee, thankthedark
Offer memory offer
and return offer
is cheaper.false
or 0
)#0 - HardlyDifficult
2022-02-28T19:19:59Z
Thanks for the feedback.
We decided to keep returning the unpacked version because this approach shields consumers from the slot packing strategy we use, and allows us to potentially make other additions or changes to the struct without impacting the external ABI. Ideally we would be more consistent here and do the same when returning the ReserveAuction struct - however there is a 3rd party contract which has already created a dependency on the current ABI.
We agree with this change as it improves readability and will switch to delete pendingWithdrawals[user]
here.
#1 - alcueca
2022-03-17T15:55:29Z
Wouldn't it be cheaper to do Offer memory offer =
and then return (offer.buyer, offer.expiration, offer.amount)
? The slot is warm, but still you should save about 300 gas.
Score: 300