-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: relay old failed messages after migration #111
Changes from 15 commits
2bd626a
ddb4aa4
aa963ea
cccad1f
1695ed4
fbe4d05
fbb0a4e
2e9514e
5d0a4de
71fecee
43e52f1
e0ff171
8133a7a
2b9a632
e0596e5
4a75bc6
e1e7eae
1e81bfa
aa81beb
3c143b2
1fd4c61
fce0118
4f06e80
3bb8d4b
a591a95
06486f9
3111a0d
86141df
4cf8ef3
b3fc454
1063e6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,13 +28,12 @@ contract L2OpUSDCBridgeAdapter is IL2OpUSDCBridgeAdapter, OpUSDCBridgeAdapter { | |
bytes4 internal constant _UPGRADE_TO_SELECTOR = 0x3659cfe6; | ||
///@notice `upgradeToAndCall(address,bytes)` USDC function selector | ||
bytes4 internal constant _UPGRADE_TO_AND_CALL_SELECTOR = 0x4f1ef286; | ||
///@notice `updateMasterMinter(address)` USDC function selector | ||
bytes4 internal constant _UPDATE_MASTER_MINTER_SELECTOR = 0xaa20e1e4; | ||
|
||
/// @inheritdoc IL2OpUSDCBridgeAdapter | ||
FallbackProxyAdmin public immutable FALLBACK_PROXY_ADMIN; | ||
|
||
/// @inheritdoc IL2OpUSDCBridgeAdapter | ||
bool public isMessagingDisabled; | ||
|
||
/// @inheritdoc IL2OpUSDCBridgeAdapter | ||
address public roleCaller; | ||
|
||
|
@@ -77,14 +76,17 @@ contract L2OpUSDCBridgeAdapter is IL2OpUSDCBridgeAdapter, OpUSDCBridgeAdapter { | |
* @param _setBurnAmountMinGasLimit Minimum gas limit that the setBurnAmount message can be executed on L1 | ||
*/ | ||
function receiveMigrateToNative(address _roleCaller, uint32 _setBurnAmountMinGasLimit) external onlyLinkedAdapter { | ||
isMessagingDisabled = true; | ||
messengerStatus = Status.Deprecated; | ||
roleCaller = _roleCaller; | ||
|
||
// We need to do totalSupply + blacklistedFunds | ||
// Because on `receiveMessage` mint would fail causing the totalSupply to not increase | ||
// But the native token is still locked on L1 | ||
uint256 _burnAmount = IUSDC(USDC).totalSupply(); | ||
|
||
// Remove the L2 Adapter as a minter | ||
IUSDC(USDC).removeMinter(address(this)); | ||
|
||
ICrossDomainMessenger(MESSENGER).sendMessage( | ||
LINKED_ADAPTER, abi.encodeCall(IL1OpUSDCBridgeAdapter.setBurnAmount, (_burnAmount)), _setBurnAmountMinGasLimit | ||
); | ||
|
@@ -115,7 +117,7 @@ contract L2OpUSDCBridgeAdapter is IL2OpUSDCBridgeAdapter, OpUSDCBridgeAdapter { | |
* @notice Receive the stop messaging message from the linked adapter and stop outgoing messages | ||
*/ | ||
function receiveStopMessaging() external onlyLinkedAdapter { | ||
isMessagingDisabled = true; | ||
messengerStatus = Status.Paused; | ||
|
||
emit MessagingStopped(MESSENGER); | ||
} | ||
|
@@ -125,7 +127,7 @@ contract L2OpUSDCBridgeAdapter is IL2OpUSDCBridgeAdapter, OpUSDCBridgeAdapter { | |
*/ | ||
function receiveResumeMessaging() external onlyLinkedAdapter { | ||
// NOTE: This is safe because this message can only be received when messaging is not deprecated on the L1 messenger | ||
isMessagingDisabled = false; | ||
messengerStatus = Status.Active; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking more about this lets add a sanity check that messengerStatus != Deprecated it doesnt hurt and helps be safe against potential sequencer ordering bugs |
||
|
||
emit MessagingResumed(MESSENGER); | ||
} | ||
|
@@ -145,19 +147,9 @@ contract L2OpUSDCBridgeAdapter is IL2OpUSDCBridgeAdapter, OpUSDCBridgeAdapter { | |
if (IUSDC(USDC).isBlacklisted(_to)) revert IOpUSDCBridgeAdapter_BlacklistedAddress(); | ||
|
||
// Ensure messaging is enabled | ||
if (isMessagingDisabled) revert IOpUSDCBridgeAdapter_MessagingDisabled(); | ||
|
||
IUSDC(USDC).safeTransferFrom(msg.sender, address(this), _amount); | ||
|
||
// Burn the tokens | ||
IUSDC(USDC).burn(_amount); | ||
|
||
// Send the message to the linked adapter | ||
ICrossDomainMessenger(MESSENGER).sendMessage( | ||
LINKED_ADAPTER, abi.encodeCall(IOpUSDCBridgeAdapter.receiveMessage, (_to, _amount)), _minGasLimit | ||
); | ||
if (messengerStatus != Status.Active) revert IOpUSDCBridgeAdapter_MessagingDisabled(); | ||
|
||
emit MessageSent(msg.sender, _to, _amount, MESSENGER, _minGasLimit); | ||
_sendMessage(msg.sender, _to, _amount, _minGasLimit); | ||
} | ||
|
||
/** | ||
|
@@ -183,7 +175,7 @@ contract L2OpUSDCBridgeAdapter is IL2OpUSDCBridgeAdapter, OpUSDCBridgeAdapter { | |
if (IUSDC(USDC).isBlacklisted(_to)) revert IOpUSDCBridgeAdapter_BlacklistedAddress(); | ||
|
||
// Ensure messaging is enabled | ||
if (isMessagingDisabled) revert IOpUSDCBridgeAdapter_MessagingDisabled(); | ||
if (messengerStatus != Status.Active) revert IOpUSDCBridgeAdapter_MessagingDisabled(); | ||
|
||
// Ensure the nonce has not already been used | ||
if (userNonces[_signer][_nonce]) revert IOpUSDCBridgeAdapter_InvalidNonce(); | ||
|
@@ -200,26 +192,24 @@ contract L2OpUSDCBridgeAdapter is IL2OpUSDCBridgeAdapter, OpUSDCBridgeAdapter { | |
// Mark the nonce as used | ||
userNonces[_signer][_nonce] = true; | ||
|
||
IUSDC(USDC).safeTransferFrom(_signer, address(this), _amount); | ||
|
||
// Burn the tokens | ||
IUSDC(USDC).burn(_amount); | ||
|
||
// Send the message to the linked adapter | ||
ICrossDomainMessenger(MESSENGER).sendMessage( | ||
LINKED_ADAPTER, abi.encodeCall(IOpUSDCBridgeAdapter.receiveMessage, (_to, _amount)), _minGasLimit | ||
); | ||
|
||
emit MessageSent(_signer, _to, _amount, MESSENGER, _minGasLimit); | ||
_sendMessage(_signer, _to, _amount, _minGasLimit); | ||
} | ||
|
||
/** | ||
* @notice Receive the message from the other chain and mint the bridged representation for the user | ||
* @dev This function should only be called when receiving a message to mint the bridged representation | ||
* @param _user The user to mint the bridged representation for | ||
* @param _spender The address that provided the tokens | ||
* @param _amount The amount of tokens to mint | ||
*/ | ||
function receiveMessage(address _user, uint256 _amount) external override onlyLinkedAdapter { | ||
function receiveMessage(address _user, address _spender, uint256 _amount) external override onlyLinkedAdapter { | ||
if (messengerStatus == Status.Deprecated) { | ||
//Return the funds to the user if the contract is deprecated | ||
// The user will need to relay the message manually with a higher gas limit | ||
ICrossDomainMessenger(MESSENGER).sendMessage( | ||
LINKED_ADAPTER, abi.encodeCall(IOpUSDCBridgeAdapter.receiveMessage, (_spender, _spender, _amount)), 0 | ||
); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this needs to be an if..else block, so the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also add a comment for why we send to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also dont use 0 as its guaranteed to fail, put like 150_000 which should usually pass |
||
// Mint the tokens to the user | ||
try IUSDC(USDC).mint(_user, _amount) { | ||
emit MessageReceived(_user, _amount, MESSENGER); | ||
|
@@ -263,7 +253,10 @@ contract L2OpUSDCBridgeAdapter is IL2OpUSDCBridgeAdapter, OpUSDCBridgeAdapter { | |
bytes4 _selector = bytes4(_data); | ||
bool _success; | ||
|
||
if (_selector == _TRANSFER_OWNERSHIP_SELECTOR || _selector == _CHANGE_ADMIN_SELECTOR) { | ||
if ( | ||
_selector == _TRANSFER_OWNERSHIP_SELECTOR || _selector == _CHANGE_ADMIN_SELECTOR | ||
|| _selector == _UPDATE_MASTER_MINTER_SELECTOR | ||
) { | ||
revert IOpUSDCBridgeAdapter_ForbiddenTransaction(); | ||
} else if (_selector == _UPGRADE_TO_SELECTOR || _selector == _UPGRADE_TO_AND_CALL_SELECTOR) { | ||
(_success,) = address(FALLBACK_PROXY_ADMIN).call(_data); | ||
|
@@ -277,4 +270,21 @@ contract L2OpUSDCBridgeAdapter is IL2OpUSDCBridgeAdapter, OpUSDCBridgeAdapter { | |
|
||
emit USDCFunctionSent(_selector); | ||
} | ||
|
||
/*/////////////////////////////////////////////////////////////// | ||
INTERNAL FUNCTIONS | ||
///////////////////////////////////////////////////////////////*/ | ||
function _sendMessage(address _from, address _to, uint256 _amount, uint32 _minGasLimit) internal { | ||
IUSDC(USDC).safeTransferFrom(_from, address(this), _amount); | ||
|
||
// Burn the tokens | ||
IUSDC(USDC).burn(_amount); | ||
|
||
// Send the message to the linked adapter | ||
ICrossDomainMessenger(MESSENGER).sendMessage( | ||
LINKED_ADAPTER, abi.encodeCall(IOpUSDCBridgeAdapter.receiveMessage, (_to, _from, _amount)), _minGasLimit | ||
); | ||
|
||
emit MessageSent(_from, _to, _amount, MESSENGER, _minGasLimit); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,9 @@ abstract contract OpUSDCBridgeAdapter is IOpUSDCBridgeAdapter, Ownable { | |
/// @inheritdoc IOpUSDCBridgeAdapter | ||
address public immutable MESSENGER; | ||
|
||
/// @inheritdoc IOpUSDCBridgeAdapter | ||
Status public messengerStatus; | ||
|
||
/// @inheritdoc IOpUSDCBridgeAdapter | ||
mapping(address _user => mapping(uint256 _nonce => bool _used)) public userNonces; | ||
|
||
|
@@ -75,9 +78,10 @@ abstract contract OpUSDCBridgeAdapter is IOpUSDCBridgeAdapter, Ownable { | |
* @notice Receive the message from the other chain and mint the bridged representation for the user | ||
* @dev This function should only be called when receiving a message to mint the bridged representation | ||
* @param _user The user to mint the bridged representation for | ||
* @param _spender The address that provided the tokens | ||
* @param _amount The amount of tokens to mint | ||
*/ | ||
function receiveMessage(address _user, uint256 _amount) external virtual; | ||
function receiveMessage(address _user, address _spender, uint256 _amount) external virtual; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider moving this function to each adapter's itnerface, since one needs the |
||
|
||
/** | ||
* @notice Withdraws the blacklisted funds from the contract if they get unblacklisted | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing NATSPEC here