Skip to content

Commit cc83ccb

Browse files
authored
[No ticket] Allow fee collection on finalized message codepath (circlefin#48)
### Summary ~Note: Leaving as a draft for now for early feedback; will flip it to a regular PR later.~ This adds fee collection support to the finalized message handling codepath in TokenMessengerV2. This is helpful to collect fees on re-signed messages that have expired, but originally consumed an allowance. Changes: - Unpack and validate the `feeExecuted` parameter on both finalized and unfinalized message handling codepaths - Unpack and validate the `expirationBlock` parameter on both finalized and unfinalized message handling codepaths. Note that for re-signed messages, `expirationBlock` should be set to 0 at launch. ### Testing The first commit adds failing tests; the 2nd commit updates the implementation such that they pass. The latter commits refactor slightly and add an additional test. To test, run the unit and integration tests.
1 parent 45dc747 commit cc83ccb

File tree

2 files changed

+470
-66
lines changed

2 files changed

+470
-66
lines changed

src/v2/TokenMessengerV2.sol

Lines changed: 43 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -247,17 +247,7 @@ contract TokenMessengerV2 is IMessageHandlerV2, BaseTokenMessenger {
247247
onlyRemoteTokenMessenger(remoteDomain, sender)
248248
returns (bool)
249249
{
250-
// Validate finalized message
251-
bytes29 _msg = messageBody.ref(0);
252-
(
253-
address _mintRecipient,
254-
bytes32 _burnToken,
255-
uint256 _amount
256-
) = _validateFinalizedMessage(_msg);
257-
258-
_mintAndWithdraw(remoteDomain, _burnToken, _mintRecipient, _amount, 0);
259-
260-
return true;
250+
return _handleReceiveMessage(messageBody.ref(0), remoteDomain);
261251
}
262252

263253
/**
@@ -291,24 +281,7 @@ contract TokenMessengerV2 is IMessageHandlerV2, BaseTokenMessenger {
291281
"Unsupported finality threshold"
292282
);
293283

294-
// Validate message
295-
bytes29 _msg = messageBody.ref(0);
296-
(
297-
address _mintRecipient,
298-
bytes32 _burnToken,
299-
uint256 _amount,
300-
uint256 _fee
301-
) = _validateUnfinalizedMessage(_msg);
302-
303-
_mintAndWithdraw(
304-
remoteDomain,
305-
_burnToken,
306-
_mintRecipient,
307-
_amount - _fee,
308-
_fee
309-
);
310-
311-
return true;
284+
return _handleReceiveMessage(messageBody.ref(0), remoteDomain);
312285
}
313286

314287
// ============ Internal Utils ============
@@ -379,46 +352,51 @@ contract TokenMessengerV2 is IMessageHandlerV2, BaseTokenMessenger {
379352
}
380353

381354
/**
382-
* @notice Validates a finalized BurnMessage and unpacks relevant message fields.
383-
* @dev Reverts if the BurnMessage is malformed
384-
* @dev Reverts if the BurnMessage version isn't supported
385-
* @param _msg Finalized message
386-
* @return _mintRecipient The recipient of the mint, as bytes32
387-
* @return _burnToken The address of the token burned on the source chain
388-
* @return _amount The amount of burnToken burned
355+
* @notice Validates a received message and mints the token to the mintRecipient, less fees.
356+
* @dev Reverts if _validatedReceivedMessage fails to validate the message.
357+
* @dev Reverts if the mint operation fails.
358+
* @param _msg Received message
359+
* @param _remoteDomain The domain where the message originated from
360+
* @return success Bool, true if successful.
389361
*/
390-
function _validateFinalizedMessage(
391-
bytes29 _msg
392-
)
393-
internal
394-
view
395-
returns (address _mintRecipient, bytes32 _burnToken, uint256 _amount)
396-
{
397-
_msg._validateBurnMessageFormat();
398-
require(
399-
_msg._getVersion() == messageBodyVersion,
400-
"Invalid message body version"
401-
);
362+
function _handleReceiveMessage(
363+
bytes29 _msg,
364+
uint32 _remoteDomain
365+
) internal returns (bool) {
366+
// Validate message and unpack fields
367+
(
368+
address _mintRecipient,
369+
bytes32 _burnToken,
370+
uint256 _amount,
371+
uint256 _fee
372+
) = _validatedReceivedMessage(_msg);
402373

403-
return (
404-
_msg._getMintRecipient().toAddress(),
405-
_msg._getBurnToken(),
406-
_msg._getAmount()
374+
// Mint tokens
375+
_mintAndWithdraw(
376+
_remoteDomain,
377+
_burnToken,
378+
_mintRecipient,
379+
_amount - _fee,
380+
_fee
407381
);
382+
383+
return true;
408384
}
409385

410386
/**
411-
* @notice Validates a finalized BurnMessage and unpacks relevant message fields.
387+
* @notice Validates a BurnMessage and unpacks relevant fields.
412388
* @dev Reverts if the BurnMessage is malformed
413389
* @dev Reverts if the BurnMessage version isn't supported
414-
* @dev Reverts if the message is expired
415-
* @dev Reverts if the fee executed exceeds the amount
390+
* @dev Reverts if the BurnMessage has expired
391+
* @dev Reverts if the fee equals or exceeds the amount
392+
* @dev Reverts if the fee exceeds the max fee specified on the source chain
416393
* @param _msg Finalized message
417394
* @return _mintRecipient The recipient of the mint, as bytes32
418395
* @return _burnToken The address of the token burned on the source chain
419396
* @return _amount The amount of burnToken burned
397+
* @return _fee The fee executed
420398
*/
421-
function _validateUnfinalizedMessage(
399+
function _validatedReceivedMessage(
422400
bytes29 _msg
423401
)
424402
internal
@@ -430,7 +408,11 @@ contract TokenMessengerV2 is IMessageHandlerV2, BaseTokenMessenger {
430408
uint256 _fee
431409
)
432410
{
433-
(_mintRecipient, _burnToken, _amount) = _validateFinalizedMessage(_msg);
411+
_msg._validateBurnMessageFormat();
412+
require(
413+
_msg._getVersion() == messageBodyVersion,
414+
"Invalid message body version"
415+
);
434416

435417
// Enforce message expiration
436418
uint256 _expirationBlock = _msg._getExpirationBlock();
@@ -440,8 +422,12 @@ contract TokenMessengerV2 is IMessageHandlerV2, BaseTokenMessenger {
440422
);
441423

442424
// Validate fee
425+
_amount = _msg._getAmount();
443426
_fee = _msg._getFeeExecuted();
444427
require(_fee == 0 || _fee < _amount, "Fee equals or exceeds amount");
445428
require(_fee <= _msg._getMaxFee(), "Fee exceeds max fee");
429+
430+
_mintRecipient = _msg._getMintRecipient().toAddress();
431+
_burnToken = _msg._getBurnToken();
446432
}
447433
}

0 commit comments

Comments
 (0)