Skip to content
$1,000,000 in security audit grants are live now, Apply here →

Security review · January 2025

USDT Arbitrum Upgrade

for USDT0

USDT0 engaged Guardian to review the security of the USDT to USDT0 migration on Arbitrum. From the 16th of January to the 20th of January, a team of 5 auditors, peer reviewed by 8 auditors reviewed the source code in scope.

Published
Review window
January 16 to 20, 2025
Language
Solidity
Chains
Arbitrum
Sector
Stablecoins
  • 0 Critical
  • 0 High
  • 0 Medium
  • 5 Low
  • 5 Informational

4 resolved · 6 acknowledged

Scope

Overview

USDT0 engaged Guardian to review the security of the USDT to USDT0 migration on Arbitrum. From the 16th of January to the 20th of January, a team of 5 auditors, peer reviewed by 8 auditors reviewed the source code in scope.

Findings 10

  1. L-01 Low Missing Storage Gaps Storage Acknowledged
    Location
    ArbitrumExtension.sol

    Description

    The current storage layout for TetherTokenV2Arbitrum is ArbitrumExtension -> EIP3009, as it inherits these 2 contracts:

    abstract contract TetherTokenV2Arbitrum is ArbitrumExtension, EIP3009 {.

    However the issue here is that ArbitrumExtension is used as a parent contract for TetherTokenV2Arbitrum, but it lacks a gap, as it's gap is inside TetherTokenV2Arbitrum meaning the storage layout is:

    l2Gateway -> l1Address -> _authorizationStates -> gap49 -> gap48

    Adding a variable inside TetherTokenV2Arbitrum would cause a storage collision between it and EIP3009's map: _authorizationStates.

    Recommendation

    Introduce a storage gap in the ArbitrumExtension contract to ensure no storage collisions if variables were to be added to that contract in future upgrades.

    Resolution

    USDT0 Team: Acknowledged.

  2. L-02 Low Incorrect Confirmations Comment Documentation Resolved
    Location
    layerzero-arbitrum-prod-step-1.config.ts.sol

    Description

    In the runbook it is mentioned as a step to: Adjust send confirmations for ETH-to-Arbitrum from 100M to 20 blocks after migration. However the configuration for the Ethereum and Arbitrum connection includes 100 Billion confirmations from the Arbitrum-to-ETH connection.

    The configuration is correct as it prevents users from bridging their USDT back from arbitrum to ETH before the migration is completed. However this is not in agreement with the comments directionality or magnitude of the confirmations.

    The exact magnitude of the confirmations count is not important as long as it is sufficiently large, however the desired direction of the large confirmations configurations should be corrected in the comment.

    Recommendation

    Update the runbook to read: Adjust send confirmations for Arbitrum-to-ETH from 100B to 20 blocks after migration.

    Resolution

    USDT0 Team: Resolved.

  3. L-03 Low In Flight Bridges Are Halted Warning Resolved
    Location
    Global

    Description

    As a part of the migration process bridges through the Arbitrum gateway will cease to function on the Arbitrum side, however will still be possible from the Ethereum side.

    This may be especially harmful for users who have initiated bridges from Ethereum to Arbitrum through the gateway right before the migration takes place.

    Any users in this scenario will experience a loss of funds as their USDT on Arbitrum can no longer be credited with the bridgeMint function and their USDT on Ethereum cannot be retrieved from the custom gateway contract.

    Recommendation

    In the migrate function of the ArbitrumExtensionV2 contract assign the l1Address storage value to address(0) after the migration has been initiated by the gateway outboundTransfer invocation.

    This will trigger refund logic in the L2ArbitrumGateway contract where a l2 to l1 token withdrawal is initiated to refund the user upon the l2 receipt of their gateway bridge.

    Notice that users will still have to wait 7 days to recoup their funds bridged through the gateway this way.

    Therefore consider putting forth a DAO proposal in the future to disable the gateway on Ethereum using the setGateways function on the L1GatewayRouter contract to assign the new gateway for the USDT address to the DISABLED address(1).

    Resolution

    USDT0 Team: Resolved.

  4. L-04 Low Incorrect _EIP712NameHash Logical Error Resolved
    Location
    ArbitrumExtension.sol: 503

    Description

    The _EIP712NameHash function is overridden to return the _newName value, however the name function returns the hardcoded value of super.name() in the case where the _newName is assigned to an empty string.

    This will mislead signers and result in the crafting of invalid signatures based on the result of the name function.

    Recommendation

    Correct the _EIP712NameHash function to be the hash of the name function.

    Resolution

    USDT0 Team: Resolved.

  5. L-05 Low Signatures Invalidated By Name Update Unexpected Behavior Acknowledged
    Location
    ArbitrumExtension.sol: 503

    Description

    Signers can create signatures with specific deadlines with ERC20Permit. The signature is typically expected to be valid until the deadline is reached.

    However since the _EIP712NameHash function is now overridden to return the latest _newName value a name update with the updateNameAndSymbol function will invalidate all signatures that were previously made based on the previous name but not yet used.

    Recommendation

    There is a trade off between using the original name of the token for the domain separator and allowing it to be updated. If the invalidation of past signatures is an acceptable downside to achieve the intuitiveness of using the current name() value in the domain separator, then no changes are necessary.

    However note that the DOMAIN_SEPARATOR is exposed as a public function through the ERC20PermitUpgradeable contract. This is what will be used by signers and therefore it is unlikely to be beneficial to base the separator on the current name() value for intuitiveness.

    If this behavior of unexpectedly invalidating signatures upon name updates is unacceptable: For new deployments of the OFTExtension it is fine to keep the same _EIP712NameHash function without an override, since this immutable value is the desired USDT0 name which the contract is initialized with.

    However for the ArbitrumExtensionV2 upgrade, the _EIP712NameHash can be overridden, but return an immutable hash which is the hash of the initial name that is assigned in the migrate function. Notice however that this update upon migration will also unexpectedly invalidate signatures, but only once during the migration.

    Otherwise no function override can be used and the original token name can continue to exist in the domain separator, making no signatures invalid.

    Resolution

    USDT0 Team: Acknowledged. 12

  6. I-01 Informational Depeg Risk Warning Acknowledged
    Location
    Global

    Description

    During the migration for approximately 7 days, USDT0 on Tether will be un-redeemable for USDT on Ethereum.

    This may introduce heightened risk of a depeg event for USDT0 on the Arbitrum network during this period.

    Although technically this is the same delay a user would typically have to wait to redeem their USDT on Arbitrum for USDT on Ethereum through the gateway, the lack of a static redemption mechanism during the in motion migration period may incite turbulence in the market.

    Recommendation

    Be aware of this risk and consider preparing a response plan in the event that a depeg event occurs during the migration.

    Resolution

    USDT0 Team: Acknowledged.

  7. I-02 Informational Bridging From Arbitrum After Migration Warning Acknowledged
    Location
    Global

    Description

    During the migration process before the l2 to l1 transaction has been confirmed and executed on Ethereum the USDT0 on Arbitrum is technically unbacked in the Ethereum OFT Adapter contract.

    If any USDT0 is allowed to bridge back to ETH from Arbitrum during this period using the Layerzero OFT pathway, it will cause a dearth in the backing ETH USDT for USDT0 on Ink which can prevent redemptions.

    This behavior is planned to be solved by assigning a restrictively high confirmations count for bridges coming from Arbitrum to Ethereum.

    This is an acceptable solution so long as users are aware that if they bridge USDT from Ethereum to Arbitrum via LayerZero that they cannot immediately bridge back until the migration is complete.

    Recommendation

    Be aware that users may still bridge from Ethereum to Arbitrum during the migration period. If this is acceptable behavior then ensure that these users or integrators are aware that they cannot bridge back to Ethereum until the migration is complete.

    Resolution

    USDT0 Team: Acknowledged.

  8. I-03 Informational Unnecessary Require Statement Superfluous Code Resolved
    Location
    ArbitrumExtension.sol: 479

    Description

    The bridgeBurn function implements a require statement which asserts that isMigrating is true. However isMigrating is immediately assigned to true in the migrate function and therefore this require statement performs no useful validation and is not needed.

    Instead the onlyAuthorizedSender access control modifier prevents future bridges through the gateway via the bridgeBurn method as the l2Gateway variable is assigned as the OFT contract after the outboundTransfer invocation.

    Recommendation

    Consider removing the require statement in the bridgeBurn function entirely as it is unnecessary.

    Resolution

    USDT0 Team: Resolved.

  9. I-04 Informational Address Aliasing Allows Blocklist Bypass Access Control Acknowledged
    Location
    ArbitrumExtension.sol

    Description

    The TetherTokenV2Arbitrum contract includes several functions which have the onlyNotBlocked modifier. These functions are intended to be uncallable by a blocked account, however l1 to l2 messages allow an address that is blocked on both l1 and l2 networks to call them.

    This is because Arbitrum l1 to l2 retryableTickets use an aliased msg.sender, shifted by an OFFSET of 0x1111000000000000000000000000000000001111. Thus the sender will not be a blocked address and these invocations are allowed.

    Specifically, since the transferWithAuthorization functions do not rely on the msg.sender as a signer, sender, or receiver a blacklisted address can call these addresses through aliasing.

    Recommendation

    There is no difference between a blacklisted address invoking this from l1 and the owner of the blacklisted address simply calling the function from a different address.

    Furthermore the main functionality of a blocked address being unable to transfer funds is still held through the _beforeTokenTransfer function. Therefore this is meant only as an informational note.

    Resolution

    USDT0 Team: Acknowledged.

  10. I-05 Informational Name Update Risk Documentation Acknowledged
    Location
    Global

    Description

    The update of the USDT token’s name to USDT0 on Arbitrum may cause unexpected behavior for other applications relying on USDT in either their Smart Contracts or Frontends.

    Recommendation

    During our review no protocols were identified that would be directly impacted on-chain. However ideally integrators can be made aware of this update and are able to make appropriate changes if necessary. If anything this finding can serve as documentation for this risk.

    Resolution

    USDT0 Team: Acknowledged.

More from USDT0

All 20 reports
  1. Stellar Deployment

    2 findings 2 findings: 2 informational
  2. Corn Network Delisting

    1 finding 1 finding: 1 low
  3. Canary Chain Configuration Verification

    4 findings 4 findings: 4 informational
  4. Solana Transaction Verification

    4 findings 4 findings: 1 medium, 3 informational

Put your code through the same review.

This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.

Get a quote