Skip to content
This repository has been archived by the owner on Dec 3, 2024. It is now read-only.

Commit

Permalink
allow sending to same blockchain but not exact same instance
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew Lam committed Mar 14, 2024
1 parent 401bb9f commit 23eef0a
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 15 deletions.
23 changes: 18 additions & 5 deletions contracts/src/TeleporterTokenDestination.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,38 @@ abstract contract TeleporterTokenDestination is
* @notice Sends tokens to the specified destination token bridge instance.
*
* @dev Burns the bridged amount, and uses Teleporter to send a cross chain message.
* Tokens can be sent to the same blockchain this bridge instance is deployed on,
* to another destination bridge instance.
* Requirements:
*
* - `input.destinationBlockchainID` cannot be the same as the current blockchainID
* - `input.destinationBridgeAddress` cannot be the zero address
* - `input.recipient` cannot be the zero address
* - `amount` must be greater than 0
* - `amount` must be greater than `input.primaryFee`
*/
function _send(SendTokensInput calldata input, uint256 amount) internal virtual {
require(
input.destinationBlockchainID != blockchainID,
"TeleporterTokenDestination: cannot bridge to same chain"
);
require(
input.destinationBridgeAddress != address(0),
"TeleporterTokenDestination: zero destination bridge address"
);
require(input.recipient != address(0), "TeleporterTokenDestination: zero recipient address");

// If the destination blockchain is the source bridge instance's blockchain,
// the destination bridge address must match the token source address.
if (input.destinationBlockchainID == sourceBlockchainID) {
require(
input.destinationBridgeAddress == tokenSourceAddress,
"TeleporterTokenDestination: invalid destination bridge address"
);
}

if (input.destinationBlockchainID == blockchainID) {
require(
input.destinationBridgeAddress != address(this),
"TeleporterTokenDestination: invalid destination bridge address"
);
}

// Deposit the funds sent from the user to the bridge,
// and set to adjusted amount after deposit
amount = _deposit(amount);
Expand Down
38 changes: 30 additions & 8 deletions contracts/test/TeleporterTokenDestinationTests.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,6 @@ contract TeleporterTokenDestinationTest is Test {
/**
* Send tokens unit tests
*/

function testSendToSameChain() public {
SendTokensInput memory input = _createDefaultSendTokensInput();
input.destinationBlockchainID = DEFAULT_DESTINATION_BLOCKCHAIN_ID;
vm.expectRevert(_formatTokenDestinationErrorMessage("cannot bridge to same chain"));
app.send(input, 0);
}

function testZeroDestinationBridge() public {
SendTokensInput memory input = _createDefaultSendTokensInput();
input.destinationBridgeAddress = address(0);
Expand All @@ -124,6 +116,21 @@ contract TeleporterTokenDestinationTest is Test {
app.send(input, 0);
}

function testInvalidSendingBackToSourceBlockchain() public {
SendTokensInput memory input = _createDefaultSendTokensInput();
input.destinationBridgeAddress = address(this);
vm.expectRevert(_formatTokenDestinationErrorMessage("invalid destination bridge address"));
app.send(input, 0);
}

function testSendingToSameInstance() public {
SendTokensInput memory input = _createDefaultSendTokensInput();
input.destinationBlockchainID = app.blockchainID();
input.destinationBridgeAddress = address(app);
vm.expectRevert(_formatTokenDestinationErrorMessage("invalid destination bridge address"));
app.send(input, 0);
}

function testZeroSendAmount() public {
vm.expectRevert(_formatTokenDestinationErrorMessage("zero send amount"));
app.send(_createDefaultSendTokensInput(), 0);
Expand All @@ -148,6 +155,21 @@ contract TeleporterTokenDestinationTest is Test {
_sendSuccess(amount, primaryFee);
}

function testSendToSameBlockchainDifferentDestination() public {
// Send a transfer to the same app itself
uint256 amount = 2;
SendTokensInput memory input = _createDefaultSendTokensInput();
input.destinationBlockchainID = app.blockchainID();
input.destinationBridgeAddress = address(this);

uint256 bridgedAmount = amount - input.primaryFee;
_checkExpectedTeleporterCalls(input, bridgedAmount);

vm.expectEmit(true, true, true, true, address(app));
emit SendTokens(_MOCK_MESSAGE_ID, address(this), bridgedAmount);
app.send(input, amount);
}

/**
* Receive tokens unit tests
*/
Expand Down
4 changes: 2 additions & 2 deletions tests/flows/basic_erc20_send_receive.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ func BasicERC20SendReceive(network interfaces.Network) {
utils.CheckERC20DestinationWithdrawal(
ctx,
erc20Destination,
receipt,
recipientAddress,
bridgedAmount,
receipt,
)

// Check that the recipient received the tokens
Expand Down Expand Up @@ -158,9 +158,9 @@ func BasicERC20SendReceive(network interfaces.Network) {
ctx,
erc20SourceAddress,
sourceToken,
receipt,
recipientAddress,
bridgedAmount,
receipt,
)

// Check that the recipient received the tokens
Expand Down

0 comments on commit 23eef0a

Please sign in to comment.