Skip to content

Commit

Permalink
refactor: implement outbound and inbound warp route amount transforms (
Browse files Browse the repository at this point in the history
…#4729)

### Description

- implements `_outbound` and `_inbound` internal amount transforms for
use in scaling warp routes
- simplify `HypNativeScaled` implementation

### Backward compatibility

Yes

### Testing

Existing HypNative Scaled Unit Tests
  • Loading branch information
yorhodes committed Nov 5, 2024
1 parent 1ed4003 commit e1049a6
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 58 deletions.
5 changes: 5 additions & 0 deletions .changeset/green-kangaroos-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hyperlane-xyz/core': patch
---

Refactor TokenRouter internal amount accounting for use in scaling Warp Routes
61 changes: 7 additions & 54 deletions solidity/contracts/token/extensions/HypNativeScaled.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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 _outboundAmount(
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 _inboundAmount(
uint256 _amount
) internal view override returns (uint256) {
return _amount * scale;
}
}
34 changes: 31 additions & 3 deletions solidity/contracts/token/libs/TokenRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,11 @@ abstract contract TokenRouter is GasRouter {
address _hook
) internal virtual returns (bytes32 messageId) {
bytes memory _tokenMetadata = _transferFromSender(_amountOrId);

uint256 outboundAmount = _outboundAmount(_amountOrId);
bytes memory _tokenMessage = TokenMessage.format(
_recipient,
_amountOrId,
outboundAmount,
_tokenMetadata
);

Expand All @@ -130,7 +132,29 @@ abstract contract TokenRouter is GasRouter {
_hook
);

emit SentTransferRemote(_destination, _recipient, _amountOrId);
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 _outboundAmount(
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 _inboundAmount(
uint256 _messageAmount
) internal view virtual returns (uint256 _localAmount) {
_localAmount = _messageAmount;
}

/**
Expand Down Expand Up @@ -163,7 +187,11 @@ 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(),
_inboundAmount(amount),
metadata
);
emit ReceivedTransferRemote(_origin, recipient, amount);
}

Expand Down
2 changes: 1 addition & 1 deletion solidity/test/token/HypNativeScaled.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit e1049a6

Please sign in to comment.