From 2c1b7723e0761e8348975c6412e368e91b9d25cc Mon Sep 17 00:00:00 2001 From: Yorke Rhodes Date: Tue, 22 Oct 2024 13:45:03 -0400 Subject: [PATCH 1/4] Implement outbound and inbound amount transforms --- .../token/extensions/HypNativeScaled.sol | 61 +++---------------- solidity/contracts/token/libs/TokenRouter.sol | 20 +++++- solidity/test/token/HypNativeScaled.t.sol | 2 +- 3 files changed, 25 insertions(+), 58 deletions(-) diff --git a/solidity/contracts/token/extensions/HypNativeScaled.sol b/solidity/contracts/token/extensions/HypNativeScaled.sol index ad129fce80..3edc64e830 100644 --- a/solidity/contracts/token/extensions/HypNativeScaled.sol +++ b/solidity/contracts/token/extensions/HypNativeScaled.sol @@ -17,62 +17,15 @@ contract HypNativeScaled is HypNative { scale = _scale; } - /** - * @inheritdoc HypNative - * @dev Sends scaled `msg.value` (divided by `scale`) to `_recipient`. - */ - function transferRemote( - uint32 _destination, - bytes32 _recipient, + function _outbound( uint256 _amount - ) external payable override returns (bytes32 messageId) { - require(msg.value >= _amount, "Native: amount exceeds msg.value"); - uint256 _hookPayment = msg.value - _amount; - uint256 _scaledAmount = _amount / scale; - return - _transferRemote( - _destination, - _recipient, - _scaledAmount, - _hookPayment - ); + ) internal view override returns (uint256) { + return _amount / scale; } - /** - * @inheritdoc TokenRouter - * @dev uses (`msg.value` - `_amount`) as hook payment. - */ - function transferRemote( - uint32 _destination, - bytes32 _recipient, - uint256 _amount, - bytes calldata _hookMetadata, - address _hook - ) external payable override returns (bytes32 messageId) { - require(msg.value >= _amount, "Native: amount exceeds msg.value"); - uint256 _hookPayment = msg.value - _amount; - uint256 _scaledAmount = _amount / scale; - return - _transferRemote( - _destination, - _recipient, - _scaledAmount, - _hookPayment, - _hookMetadata, - _hook - ); - } - - /** - * @dev Sends scaled `_amount` (multiplied by `scale`) to `_recipient`. - * @inheritdoc TokenRouter - */ - function _transferTo( - address _recipient, - uint256 _amount, - bytes calldata metadata // no metadata - ) internal override { - uint256 scaledAmount = _amount * scale; - HypNative._transferTo(_recipient, scaledAmount, metadata); + function _inbound( + uint256 _amount + ) internal view override returns (uint256) { + return _amount * scale; } } diff --git a/solidity/contracts/token/libs/TokenRouter.sol b/solidity/contracts/token/libs/TokenRouter.sol index 96ffcf8385..9663a9a8e3 100644 --- a/solidity/contracts/token/libs/TokenRouter.sol +++ b/solidity/contracts/token/libs/TokenRouter.sol @@ -116,9 +116,11 @@ abstract contract TokenRouter is GasRouter { address _hook ) internal virtual returns (bytes32 messageId) { bytes memory _tokenMetadata = _transferFromSender(_amountOrId); + + uint256 outboundAmount = _outbound(_amountOrId); bytes memory _tokenMessage = TokenMessage.format( _recipient, - _amountOrId, + outboundAmount, _tokenMetadata ); @@ -130,7 +132,19 @@ abstract contract TokenRouter is GasRouter { _hook ); - emit SentTransferRemote(_destination, _recipient, _amountOrId); + emit SentTransferRemote(_destination, _recipient, outboundAmount); + } + + function _outbound( + uint256 _amountOrId + ) internal view virtual returns (uint256) { + return _amountOrId; + } + + function _inbound( + uint256 _amountOrId + ) internal view virtual returns (uint256) { + return _amountOrId; } /** @@ -163,7 +177,7 @@ abstract contract TokenRouter is GasRouter { bytes32 recipient = _message.recipient(); uint256 amount = _message.amount(); bytes calldata metadata = _message.metadata(); - _transferTo(recipient.bytes32ToAddress(), amount, metadata); + _transferTo(recipient.bytes32ToAddress(), _inbound(amount), metadata); emit ReceivedTransferRemote(_origin, recipient, amount); } diff --git a/solidity/test/token/HypNativeScaled.t.sol b/solidity/test/token/HypNativeScaled.t.sol index ffded65655..47899ae89e 100644 --- a/solidity/test/token/HypNativeScaled.t.sol +++ b/solidity/test/token/HypNativeScaled.t.sol @@ -144,7 +144,7 @@ contract HypNativeScaledTest is Test { environment.processNextPendingMessage(); } - function test_tranferRemote(uint256 amount) public { + function test_transferRemote(uint256 amount) public { vm.assume(amount <= mintAmount); uint256 nativeValue = amount * (10 ** nativeDecimals); From 2c96dd2e2025c849c461326b499e6726e492ccad Mon Sep 17 00:00:00 2001 From: Yorke Rhodes Date: Tue, 22 Oct 2024 15:13:51 -0400 Subject: [PATCH 2/4] Add doc strings --- solidity/contracts/token/libs/TokenRouter.sol | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/solidity/contracts/token/libs/TokenRouter.sol b/solidity/contracts/token/libs/TokenRouter.sol index 9663a9a8e3..a7498aacbb 100644 --- a/solidity/contracts/token/libs/TokenRouter.sol +++ b/solidity/contracts/token/libs/TokenRouter.sol @@ -135,16 +135,26 @@ abstract contract TokenRouter is GasRouter { emit SentTransferRemote(_destination, _recipient, outboundAmount); } + /** + * @dev Should return the amount of tokens to be encoded in the message amount (eg for scaling `_localAmount`). + * @param _localAmount The amount of tokens transferred on this chain in local denomination. + * @return _messageAmount The amount of tokens to be encoded in the message body. + */ function _outbound( - uint256 _amountOrId - ) internal view virtual returns (uint256) { - return _amountOrId; + uint256 _localAmount + ) internal view virtual returns (uint256 _messageAmount) { + _messageAmount = _localAmount; } + /** + * @dev Should return the amount of tokens to be decoded from the message amount. + * @param _messageAmount The amount of tokens received in the message body. + * @return _localAmount The amount of tokens to be transferred on this chain in local denomination. + */ function _inbound( - uint256 _amountOrId - ) internal view virtual returns (uint256) { - return _amountOrId; + uint256 _messageAmount + ) internal view virtual returns (uint256 _localAmount) { + _localAmount = _messageAmount; } /** From 73063da54b38963a35dfbc648246b22f1545bd41 Mon Sep 17 00:00:00 2001 From: Yorke Rhodes Date: Tue, 22 Oct 2024 15:15:21 -0400 Subject: [PATCH 3/4] docs(changeset): Refactor TokenRouter internal amount accounting for use in scaling Warp Routes --- .changeset/green-kangaroos-whisper.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/green-kangaroos-whisper.md diff --git a/.changeset/green-kangaroos-whisper.md b/.changeset/green-kangaroos-whisper.md new file mode 100644 index 0000000000..aa3212a5a5 --- /dev/null +++ b/.changeset/green-kangaroos-whisper.md @@ -0,0 +1,5 @@ +--- +'@hyperlane-xyz/core': patch +--- + +Refactor TokenRouter internal amount accounting for use in scaling Warp Routes From 81c09ab38b343c7b7cfd2d7b18aaa1ae3ea5e5d5 Mon Sep 17 00:00:00 2001 From: Yorke Rhodes Date: Tue, 22 Oct 2024 16:23:43 -0400 Subject: [PATCH 4/4] Rename internal functions --- .../contracts/token/extensions/HypNativeScaled.sol | 4 ++-- solidity/contracts/token/libs/TokenRouter.sol | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/solidity/contracts/token/extensions/HypNativeScaled.sol b/solidity/contracts/token/extensions/HypNativeScaled.sol index 3edc64e830..605ec87b92 100644 --- a/solidity/contracts/token/extensions/HypNativeScaled.sol +++ b/solidity/contracts/token/extensions/HypNativeScaled.sol @@ -17,13 +17,13 @@ contract HypNativeScaled is HypNative { scale = _scale; } - function _outbound( + function _outboundAmount( uint256 _amount ) internal view override returns (uint256) { return _amount / scale; } - function _inbound( + function _inboundAmount( uint256 _amount ) internal view override returns (uint256) { return _amount * scale; diff --git a/solidity/contracts/token/libs/TokenRouter.sol b/solidity/contracts/token/libs/TokenRouter.sol index a7498aacbb..8a474acea3 100644 --- a/solidity/contracts/token/libs/TokenRouter.sol +++ b/solidity/contracts/token/libs/TokenRouter.sol @@ -117,7 +117,7 @@ abstract contract TokenRouter is GasRouter { ) internal virtual returns (bytes32 messageId) { bytes memory _tokenMetadata = _transferFromSender(_amountOrId); - uint256 outboundAmount = _outbound(_amountOrId); + uint256 outboundAmount = _outboundAmount(_amountOrId); bytes memory _tokenMessage = TokenMessage.format( _recipient, outboundAmount, @@ -140,7 +140,7 @@ abstract contract TokenRouter is GasRouter { * @param _localAmount The amount of tokens transferred on this chain in local denomination. * @return _messageAmount The amount of tokens to be encoded in the message body. */ - function _outbound( + function _outboundAmount( uint256 _localAmount ) internal view virtual returns (uint256 _messageAmount) { _messageAmount = _localAmount; @@ -151,7 +151,7 @@ abstract contract TokenRouter is GasRouter { * @param _messageAmount The amount of tokens received in the message body. * @return _localAmount The amount of tokens to be transferred on this chain in local denomination. */ - function _inbound( + function _inboundAmount( uint256 _messageAmount ) internal view virtual returns (uint256 _localAmount) { _localAmount = _messageAmount; @@ -187,7 +187,11 @@ abstract contract TokenRouter is GasRouter { bytes32 recipient = _message.recipient(); uint256 amount = _message.amount(); bytes calldata metadata = _message.metadata(); - _transferTo(recipient.bytes32ToAddress(), _inbound(amount), metadata); + _transferTo( + recipient.bytes32ToAddress(), + _inboundAmount(amount), + metadata + ); emit ReceivedTransferRemote(_origin, recipient, amount); }