Platform: Code4rena
Start Date: 05/10/2023
Pot Size: $33,050 USDC
Total HM: 1
Participants: 54
Period: 6 days
Judge: hansfriese
Id: 294
League: ETH
Rank: 2/54
Findings: 2
Award: $1,846.79
π Selected for report: 1
π Solo Findings: 0
1774.1935 USDC - $1,774.19
Judge has assessed an item in Issue #272 as 2 risk. The relevant finding follows:
ERC1155 can be inflated if the token doesnβt revert on failed transfer
#0 - c4-judge
2023-10-25T17:17:52Z
hansfriese marked the issue as satisfactory
#1 - c4-judge
2023-10-25T17:18:00Z
hansfriese marked the issue as duplicate of #91
#2 - c4-judge
2023-10-28T06:24:16Z
hansfriese marked the issue as duplicate of #90
#3 - midori-fuse
2023-10-28T07:56:50Z
I think this should be duped with #91 instead of #90 , the report has mentioned impact of both mentioned issues, so the higher impact issue should be considered.
#4 - hansfriese
2023-10-28T08:14:18Z
Thanks for your comment. I agree it's eligible to be a high risk.
#5 - c4-judge
2023-10-28T08:14:36Z
hansfriese marked the issue as not a duplicate
#6 - c4-judge
2023-10-28T08:14:42Z
hansfriese changed the severity to 3 (High Risk)
#7 - c4-judge
2023-10-28T08:15:10Z
hansfriese marked the issue as duplicate of #91
#8 - c4-judge
2023-10-29T10:13:32Z
hansfriese changed the severity to 2 (Med Risk)
π Selected for report: thekmj
Also found by: 0x3b, 33BYTEZZZ, Bauchibred, Chom, Dravee, J4X, Limbooo, Maroutis, MiloTruck, MrPotatoMagic, SBSecurity, Sathish9098, Tadev, ZanyBonzy, adam-idarrha, adriro, btk, hyh, lukejohn, nmirchev8, peakbolt, radev_sw, rvierdiiev
72.599 USDC - $72.60
assert()
does not provide any information when thrown.This finding escalates [N-09] of the automated report.
https://github.com/code-423n4/2023-10-ens/blob/main/contracts/ERC20MultiDelegate.sol#L131
The following assertion will throw when the usre attempts to re-delegate more than the existing amount. Using assert
here has the following two issues:
assert
does not provide any error message when thrown, while it should have been reported told as an Insufficient balance
error message or similar._burnBatch
call anyway, as the owner would not have enough ERC1155 to burn.We suggest changing assert
to a require
statement, with a clear error message, or using custom errors.
While the only ERC20 token that the contract interacts with is the designated token with voting capability, if the token does not revert on failed transfer (e.g. transfer exceeds balance), then anyone can infinitely mint the ERC1155 token. This can be extended into a honeypot attack vector that can steal funds from succeeded transfers.
POC:
delegateMulti
.Alice can be aware of Bob's delegatee by simply front-running.
We recognize this as a low severity issue because, while the impact is high, we could not identify such a token with both voting capability and doesn't revert on failed transfer. However we do not rule out the possibility that such a token does exist.
The recommended mitigation method is to use OpenZeppelin's safeTransfer
.
onERC115Received
The ERC721 token, closely related to ERC1155, has a _safeMint
mechanism, where a contract recipient must implement onERC721Received
to receive the minted NFT, otherwise the call will revert. This is to ensure that contract NFTs cannot be stuck in smart contracts.
However, in OpenZeppelin's ERC1155, the function _mintBatch()
requires that a contract user must be able to accept the token, that is, it implements the ERC721-like safe mint mechanism by default.
This brings forth an edge case where contract recipients (e.g. multisigs) may fail to delegate due to not being able to accept the token. We urge the sponsor to double check on whether this is the intended mechanism.
The ERC20MultiDelegate
splits delegation by wrapping ENS, and tokenizing it into an ERC1155, with the id being the delegatee. We note some of the behaviors that we, as a user, may not expect it to have:
ERC20MultiDelegate
ERC1155, transferring the token retains the voting power to the current delegatee.
ERC20MultiDelegate
is equivalent to transferring away ENS. The token may show up on block explorers such as etherscan, and users may attempt to transfer it away, losing their funds as a result.
These are some behaviors of the token that we find, while logically sound, should not be unexpected for a user to deduce at first usage, and users should be made aware of the vote tokenizing mechanism to prevent accidentally losing funds.
delegateMulti()
When delegateMulti()
is called, ERC1155 tokens may be minted. However, following ERC1155 standards, the recipient must either be an EOA, or a contract implementing ERC1155Holder
, or tx will revert.
While this should be the correct and intended behavior, the fact that ERC1155 is minted is not documented in the function. This may cause unintended reverts to e.g. multisigs, or other interacting contracts.
delegateMulti()
should be protected with a reentrancy guard.The function delegateMulti()
may mint ERC1155 tokens, which in turn may invoke a onERC1155Received()
at the recipient (if it is a contract). This opens up potential for reentrancy.
While we evaluated that the function correctly follows the CEI pattern and did not identify a potential attack vector, we do believe a proper reentrancy guard in place is good practice.
_reimburse()
docs is slightly inconsistent with its behaviorThe docs for function _reimburse()
mentions
/** * @dev Reimburses any remaining source amounts back to the delegator after the delegation transfer process. * @param source The source delegate from which tokens are being withdrawn. * @param amount The amount of tokens to be withdrawn from the source delegate. */ // ... // Transfer the remaining source amount or the full source amount // (if no remaining amount) to the delegator
However the function always (attempt to) transfers exactly amount
, which should be specified as a function parameter earlier in the delegateMulti()
call. This is inconsistent with the documentation
The contract name is ERC20MultiDelegate
, strongly implying it is an ERC20 token. Such naming can cause confusion, as:
We suggest a more descriptive name, such as ERC20VotesMultiDelegateWrapper
.
#0 - 141345
2023-10-13T12:11:58Z
L-02 is dup of https://github.com/code-423n4/2023-10-ens-findings/issues/91
L-03 is dup of https://github.com/code-423n4/2023-10-ens-findings/issues/473
#1 - c4-pre-sort
2023-10-13T12:12:04Z
141345 marked the issue as sufficient quality report
#2 - c4-pre-sort
2023-10-14T15:34:57Z
141345 marked the issue as high quality report
#3 - Arachnid
2023-10-16T10:06:12Z
Agree except N-02; reentrancy guards are a bandaid for poorly written code, and using one here would waste gas.
#4 - c4-sponsor
2023-10-16T10:06:18Z
Arachnid (sponsor) confirmed
#5 - c4-judge
2023-10-24T15:41:37Z
hansfriese marked the issue as grade-a
#6 - hansfriese
2023-10-25T17:48:45Z
[L-02] => Med [S-01] => Non-critical
#7 - c4-judge
2023-10-25T17:48:53Z
hansfriese marked the issue as selected for report
#8 - c4-judge
2023-10-26T18:09:49Z
hansfriese marked the issue as not selected for report
#9 - c4-judge
2023-10-26T18:10:05Z
hansfriese marked the issue as selected for report