Open c4-bot-5 opened 5 months ago
minhquanym marked the issue as insufficient quality report
OOS in bot report
0xean marked the issue as unsatisfactory: Out of scope
Hi @0xean, I think this issue should technically be valid due to multiple reasons:
First, let's understand the scope of tokens the bridge interacts with as per the README here on the first line. This means the all ERC-XXX compliant tokens should be considered.
Our vaults are designed to work with all ERC20, ERC1155, and ERC721 tokens, respectively.
Regarding the low-severity issues covered by the bot report here, we can see that it only covers decimals() in [L-03] and symbol() in [L-10]. It nowhere mentions the name() function (even in it's instances) which is optional for both the ERC20 and ERC721 specifications (as detailed in my report above).
Additionally, the bot report does not entail instances and mention another pain point in the execution flow which prevents the bridging i.e. when the bridged token is being deployed on the destination chain, the validateInput() function reverts when the name and symbol values are empty (same case for ERC721).
Overall, I think the bot report is insufficient in detailing the issue and instances where the issues in the execution flow could've arised.
Thank you for your time!
will upgrade to QA.
0xean removed the grade
0xean changed the severity to QA (Quality Assurance)
0xean marked the issue as grade-a
Hi @0xean, I believe this issue should a valid Medium-severity.
Our vaults are designed to work with all ERC20, ERC1155, and ERC721 tokens, respectively.
In short, the bot report does not include function name() anywhere and an additional issue is being overlooked in the execution flow on the destination chain.
Overall, since the intended functionality of the protocol is impacted (i.e. valid ERC20 and ERC721 tokens are devoid of being bridged), I think this should be upgraded to Medium.
2 — Med: Assets not at direct risk, but the function of the protocol or its availability could be impacted, or leak value with a hypothetical attack path with stated assumptions, but external requirements.
Tagging @adaki2004 @dantaik to gather their view.
I think this should clearly classify as a Medium-severity issue based on the C4 docs Med definition (intended functionality of the protocol defined by sponsors in the README is not available) and the two points mentioned above.
this is finalized.
Tagging @adaki2004 @dantaik to gather their view.
I think this should clearly classify as a Medium-severity issue based on the C4 docs Med definition (intended functionality of the protocol defined by sponsors in the README is not available) and the two points mentioned above.
I'd rather say that this description is not fully correct on our side - because there can be contracts which are simply just not possible to work with - for example the aforementioned reasons.
Our vaults are designed to work with all ERC20, ERC1155, and ERC721 tokens, respectively.
If clearly this can be an issue - it is during initial bridgind so worst case what could happen is the revert during bridging. No assets are at risk, but I'd consider it a QA (wrong commenting), maximum low severity, personally.
Hi @adaki2004 and @0xean,
I'm sure that the protocol was intended to work with atleast ERC20-compliant and ERC721-compliant tokens. I would've agreed if this was something about rebasing tokens or other weird tokens but the README had clearly defined this during the contest, which could also be seen in how ERC1155Vault handles the name(), symbol() and decimals() issue here I'm mentioning above in my report.
Regarding the severity, I think it classifies as Medium since the intended functionality defined is not available. Here is the C4 docs:
2 — Med: Assets not at direct risk, but the function of the protocol or its availability could be impacted, or leak value with a hypothetical attack path with stated assumptions, but external requirements.
How does it complies with this below ?
function of the protocol or its availability could be impacted, or leak value with a hypothetical attack path with stated assumptions, but external requirements.
I dont see functions impacted, but only transactions rejected, we can argue about semantics that functions vs. transactions but dont think it makes sense.
I agree and will not deny that e.g.: name is option in ERC20() but can you name any (valuable/semi-valuable) coins that are lacking these functionalities ? Also in case they are lacking the name / smybol -> What would be the name on our L2 ? Shall we make up a random name/symbol for them ?
If the probability to happen is low
, impact is (max) medium
(impact is: coin is not able to be bridged, but no loss of funds, simply no support.) -> This is a abs. max a low. Sorry, usually i'm flexible and happy to judge in favor of warden, but the best i would offer here is a low.
@mcgrathcoutinho - this is finalized, if you decide to continue arguing I will downgrade this to C
My intention was not to argue, sorry if I sounded like that.
Though a low-severity issue, I hope the sponsor found this issue to be valuable.
Thank you for your responses. Will agree to the current ruling by the judge and the sponsor comments above.
Lines of code
https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/tokenvault/ERC20Vault.sol#L369 https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/tokenvault/ERC721Vault.sol#L206
Vulnerability details
Impact
According to the README here, all vaults are designed to work with all ERC20, ERC721 and ERC1155 tokens, respectively.
The issue is with the ERC20Vault and ERC721Vault contracts which expect canonical tokens to implement the functions name(), symbol() (in case of both ERC20 and ERC721) and decimals() (in case of ERC20 only).
According to the EIP-20 specification, functions name(), symbol() and decimals() are OPTIONAL and other contracts (in this case the vaults) MUST NOT expect these values to be present.
According to the EIP-721 specification, the metadata extension, which includes functions name() and symbol(), is optional.
Since both the ERC20Vault and ERC721Vault expect these functions to be present by calling them here and here, the calls would revert. This disallows valid ERC-20 and ERC=721 compliant canonical tokens from being bridged.
The issue does not exist in the ERC1155Vualt since it considers for this situation here by implementing a try-catch block.
Proof of Concept
When the function sendToken() in the ERC20Vault/ERC721Vault is called by the user, it internally calls function _handleMessage(). If the
_token
parameter is a canonical token, we enter the else block on Line 376 for ERC20Vault and Line 204 for ERC721Vault.In the else block, we can see that the functions name(), symbol() and decimals() are directly being called on the canonical token. Since these are optional, the function will revert and prevent users from bridging valid ERC20 and ERC721 compliant tokens.
Function _handleMessage() in ERC20Vault:
Function _handleMessage() in ERC721Vault:
Unlike the two vaults above, the ERC1155Vault considers this case by implementing a try-catch block on Line 286 for the functions name() and symbol().
Function _handleMessage() in ERC1155Vault:
Note: For the EIP-20 specification, there is a bit of ambiguity whether the functions themselves are optional or the values for the three functions.
In case the values for the functions name(), symbol() and decimals() are optional, there is still a problem though.
When a BridgedERC20 token is deployed on the destination chain through function _deployBridgedToken() (this happens during bridging a canonical token for the first time from source), the init() function on the BridgedERC20 contract validates the name and symbol inputs here, which expects them to be non-zero as seen here in LibBridgedToken. Due to the possibility of the values being empty as per the specification, the call would revert on the destination chain, causing the same impact of valid ERC20 compliant canonical token being devoid of bridging. The same applies for the ERC721 case.
Once again, we can see that this issue does not exist in the ERC1155Vault contract since it is mitigated by the team by passing placeholder data on Line 53.
Tools Used
Manual Review
Recommended Mitigation Steps
Similar to the ERC1155Vault, consider implementing a try-catch block for name(), symbol() and decimals() in ERC20Vault and ERC721Vault.
Note that the BridgedERC20 and BridgedERC721 token contracts would need to be updated as well since they currently validate the name and symbol inputs here and here to be non-zero values. Since according to the EIP, these values can be empty, the calls on destination would always revert. This issue does not exist in BridgedERC1155 since it uses placeholder data here to avoid reverting when a new bridge token is being deployed/created for the canonical token through the vault here.
Assessed type
ERC20