diff --git a/packages/contracts-periphery/contracts/L1/L1ERC721Bridge.sol b/packages/contracts-periphery/contracts/L1/L1ERC721Bridge.sol index 947b85ebdaae2..db68f4099f1cb 100644 --- a/packages/contracts-periphery/contracts/L1/L1ERC721Bridge.sol +++ b/packages/contracts-periphery/contracts/L1/L1ERC721Bridge.sol @@ -95,7 +95,9 @@ contract L1ERC721Bridge is Semver, CrossDomainEnabled, OwnableUpgradeable { } /** - * @notice Initiates a bridge of an NFT to the caller's account on L2. + * @notice Initiates a bridge of an NFT to the caller's account on L2. Note that this function + * can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` + * function after ensuring that the recipient address on the remote chain exists. * * @param _localToken Address of the ERC721 on this domain. * @param _remoteToken Address of the ERC721 on the remote domain. @@ -112,8 +114,12 @@ contract L1ERC721Bridge is Semver, CrossDomainEnabled, OwnableUpgradeable { uint32 _minGasLimit, bytes calldata _extraData ) external { - // Modifier requiring sender to be EOA. This check could be bypassed by a malicious - // contract via initcode, but it takes care of the user error we want to avoid. + // Modifier requiring sender to be EOA. This prevents against a user error that would occur + // if the sender is a smart contract wallet that has a different address on the remote chain + // (or doesn't have an address on the remote chain at all). The user would fail to receive + // the NFT if they use this function because it sends the NFT to the same address as the + // caller. This check could be bypassed by a malicious contract via initcode, but it takes + // care of the user error we want to avoid. require(!Address.isContract(msg.sender), "L1ERC721Bridge: account is not externally owned"); _initiateBridgeERC721( diff --git a/packages/contracts-periphery/contracts/L2/L2ERC721Bridge.sol b/packages/contracts-periphery/contracts/L2/L2ERC721Bridge.sol index 237dcdd4de9cb..44484f5b23c61 100644 --- a/packages/contracts-periphery/contracts/L2/L2ERC721Bridge.sol +++ b/packages/contracts-periphery/contracts/L2/L2ERC721Bridge.sol @@ -109,7 +109,9 @@ contract L2ERC721Bridge is Semver, CrossDomainEnabled, OwnableUpgradeable { } /** - * @notice Initiates a bridge of an NFT to the caller's account on L1. + * @notice Initiates a bridge of an NFT to the caller's account on L1. Note that this function + * can only be called by EOAs. Smart contract wallets should use the `bridgeERC721To` + * function after ensuring that the recipient address on the remote chain exists. * * @param _localToken Address of the ERC721 on this domain. * @param _remoteToken Address of the ERC721 on the remote domain. @@ -126,8 +128,12 @@ contract L2ERC721Bridge is Semver, CrossDomainEnabled, OwnableUpgradeable { uint32 _minGasLimit, bytes calldata _extraData ) external { - // Modifier requiring sender to be EOA. This check could be bypassed by a malicious - // contract via initcode, but it takes care of the user error we want to avoid. + // Modifier requiring sender to be EOA. This prevents against a user error that would occur + // if the sender is a smart contract wallet that has a different address on the remote chain + // (or doesn't have an address on the remote chain at all). The user would fail to receive + // the NFT if they use this function because it sends the NFT to the same address as the + // caller. This check could be bypassed by a malicious contract via initcode, but it takes + // care of the user error we want to avoid. require(!Address.isContract(msg.sender), "L2ERC721Bridge: account is not externally owned"); _initiateBridgeERC721(