This repository has been archived by the owner on Dec 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into gstuart/native-token-destination
- Loading branch information
Showing
22 changed files
with
628 additions
and
525 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
lib/ |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,8 +7,6 @@ pragma solidity 0.8.18; | |
|
||
import {TeleporterTokenSource} from "./TeleporterTokenSource.sol"; | ||
import {INativeTokenBridge} from "./interfaces/INativeTokenBridge.sol"; | ||
import {IERC20} from "@openzeppelin/[email protected]/token/ERC20/ERC20.sol"; | ||
import {SafeERC20} from "@openzeppelin/[email protected]/token/ERC20/utils/SafeERC20.sol"; | ||
import {SendTokensInput} from "./interfaces/ITeleporterTokenBridge.sol"; | ||
import {IWrappedNativeToken} from "./interfaces/IWrappedNativeToken.sol"; | ||
|
||
|
@@ -24,8 +22,6 @@ import {IWrappedNativeToken} from "./interfaces/IWrappedNativeToken.sol"; | |
* token bridge instance. | ||
*/ | ||
contract NativeTokenSource is INativeTokenBridge, TeleporterTokenSource { | ||
using SafeERC20 for IERC20; | ||
|
||
/** | ||
* @notice The wrapped native token contract that represents the native tokens on this chain. | ||
*/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// (c) 2024, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
// SPDX-License-Identifier: Ecosystem | ||
|
||
pragma solidity 0.8.18; | ||
|
||
import {TeleporterTokenBridgeTest} from "./TeleporterTokenBridgeTests.t.sol"; | ||
import {IERC20Bridge} from "../src/interfaces/IERC20Bridge.sol"; | ||
import {SendTokensInput} from "../src/interfaces/ITeleporterTokenBridge.sol"; | ||
import {IERC20} from "@openzeppelin/[email protected]/token/ERC20/IERC20.sol"; | ||
import {SafeERC20} from "@openzeppelin/[email protected]/token/ERC20/utils/SafeERC20.sol"; | ||
|
||
abstract contract ERC20BridgeTest is TeleporterTokenBridgeTest { | ||
using SafeERC20 for IERC20; | ||
|
||
IERC20Bridge public erc20Bridge; | ||
|
||
function testZeroSendAmount() public { | ||
vm.expectRevert("SafeERC20TransferFrom: balance not increased"); | ||
_send(_createDefaultSendTokensInput(), 0); | ||
} | ||
|
||
function _send(SendTokensInput memory input, uint256 amount) internal virtual override { | ||
erc20Bridge.send(input, amount); | ||
} | ||
|
||
function _setUpExpectedDeposit(uint256 amount) internal virtual override { | ||
// Increase the allowance of the bridge to transfer the funds from the user | ||
feeToken.safeIncreaseAllowance(address(tokenBridge), amount); | ||
// Check that transferFrom is called to deposit the funds sent from the user to the bridge | ||
vm.expectCall( | ||
address(feeToken), | ||
abi.encodeCall(IERC20.transferFrom, (address(this), address(tokenBridge), amount)) | ||
); | ||
vm.expectEmit(true, true, true, true, address(feeToken)); | ||
emit Transfer(address(this), address(tokenBridge), amount); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// (c) 2024, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
// SPDX-License-Identifier: Ecosystem | ||
|
||
pragma solidity 0.8.18; | ||
|
||
import {ERC20BridgeTest} from "./ERC20BridgeTests.t.sol"; | ||
import {TeleporterTokenDestinationTest} from "./TeleporterTokenDestinationTests.t.sol"; | ||
import {ERC20Destination} from "../src/ERC20Destination.sol"; | ||
import {IERC20} from "@openzeppelin/[email protected]/token/ERC20/IERC20.sol"; | ||
import {SafeERC20} from "@openzeppelin/[email protected]/token/ERC20/utils/SafeERC20.sol"; | ||
|
||
contract ERC20DestinationTest is ERC20BridgeTest, TeleporterTokenDestinationTest { | ||
using SafeERC20 for IERC20; | ||
|
||
ERC20Destination public app; | ||
|
||
string public constant MOCK_TOKEN_NAME = "Test Token"; | ||
string public constant MOCK_TOKEN_SYMBOL = "TST"; | ||
uint8 public constant MOCK_TOKEN_DECIMALS = 18; | ||
|
||
function setUp() public virtual override { | ||
TeleporterTokenDestinationTest.setUp(); | ||
|
||
app = new ERC20Destination({ | ||
teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, | ||
teleporterManager: address(this), | ||
sourceBlockchainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, | ||
tokenSourceAddress: TOKEN_SOURCE_ADDRESS, | ||
tokenName: MOCK_TOKEN_NAME, | ||
tokenSymbol: MOCK_TOKEN_SYMBOL, | ||
tokenDecimals: MOCK_TOKEN_DECIMALS | ||
}); | ||
|
||
erc20Bridge = app; | ||
tokenDestination = app; | ||
tokenBridge = app; | ||
feeToken = IERC20(app); | ||
|
||
vm.expectEmit(true, true, true, true, address(app)); | ||
emit Transfer(address(0), address(this), 10e18); | ||
|
||
vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); | ||
app.receiveTeleporterMessage( | ||
DEFAULT_SOURCE_BLOCKCHAIN_ID, TOKEN_SOURCE_ADDRESS, abi.encode(address(this), 10e18) | ||
); | ||
} | ||
|
||
/** | ||
* Initialization unit tests | ||
*/ | ||
function testZeroTeleporterRegistryAddress() public { | ||
vm.expectRevert("TeleporterUpgradeable: zero teleporter registry address"); | ||
new ERC20Destination({ | ||
teleporterRegistryAddress: address(0), | ||
teleporterManager: address(this), | ||
sourceBlockchainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, | ||
tokenSourceAddress: TOKEN_SOURCE_ADDRESS, | ||
tokenName: MOCK_TOKEN_NAME, | ||
tokenSymbol: MOCK_TOKEN_SYMBOL, | ||
tokenDecimals: MOCK_TOKEN_DECIMALS | ||
}); | ||
} | ||
|
||
function testZeroTeleporterManagerAddress() public { | ||
vm.expectRevert("Ownable: new owner is the zero address"); | ||
new ERC20Destination({ | ||
teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, | ||
teleporterManager: address(0), | ||
sourceBlockchainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, | ||
tokenSourceAddress: TOKEN_SOURCE_ADDRESS, | ||
tokenName: MOCK_TOKEN_NAME, | ||
tokenSymbol: MOCK_TOKEN_SYMBOL, | ||
tokenDecimals: MOCK_TOKEN_DECIMALS | ||
}); | ||
} | ||
|
||
function testZeroBlockchainID() public { | ||
vm.expectRevert(_formatErrorMessage("zero source blockchain ID")); | ||
new ERC20Destination({ | ||
teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, | ||
teleporterManager: address(this), | ||
sourceBlockchainID: bytes32(0), | ||
tokenSourceAddress: TOKEN_SOURCE_ADDRESS, | ||
tokenName: MOCK_TOKEN_NAME, | ||
tokenSymbol: MOCK_TOKEN_SYMBOL, | ||
tokenDecimals: MOCK_TOKEN_DECIMALS | ||
}); | ||
} | ||
|
||
function testDeployToSameBlockchain() public { | ||
vm.expectRevert(_formatErrorMessage("cannot deploy to same blockchain as source")); | ||
new ERC20Destination({ | ||
teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, | ||
teleporterManager: address(this), | ||
sourceBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, | ||
tokenSourceAddress: TOKEN_SOURCE_ADDRESS, | ||
tokenName: MOCK_TOKEN_NAME, | ||
tokenSymbol: MOCK_TOKEN_SYMBOL, | ||
tokenDecimals: MOCK_TOKEN_DECIMALS | ||
}); | ||
} | ||
|
||
function testZeroTokenSourceAddress() public { | ||
vm.expectRevert(_formatErrorMessage("zero token source address")); | ||
new ERC20Destination({ | ||
teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, | ||
teleporterManager: address(this), | ||
sourceBlockchainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, | ||
tokenSourceAddress: address(0), | ||
tokenName: MOCK_TOKEN_NAME, | ||
tokenSymbol: MOCK_TOKEN_SYMBOL, | ||
tokenDecimals: MOCK_TOKEN_DECIMALS | ||
}); | ||
} | ||
|
||
function _checkExpectedWithdrawal(address recipient, uint256 amount) internal override { | ||
vm.expectEmit(true, true, true, true, address(app)); | ||
emit Transfer(address(0), recipient, amount); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// (c) 2024, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
// SPDX-License-Identifier: Ecosystem | ||
|
||
pragma solidity 0.8.18; | ||
|
||
import {ERC20BridgeTest} from "./ERC20BridgeTests.t.sol"; | ||
import {TeleporterTokenSourceTest} from "./TeleporterTokenSourceTests.t.sol"; | ||
import {ERC20Source} from "../src/ERC20Source.sol"; | ||
import {IERC20} from "@openzeppelin/[email protected]/token/ERC20/IERC20.sol"; | ||
import {SafeERC20} from "@openzeppelin/[email protected]/token/ERC20/utils/SafeERC20.sol"; | ||
import {ExampleERC20} from "../lib/teleporter/contracts/src/Mocks/ExampleERC20.sol"; | ||
|
||
contract ERC20SourceTest is ERC20BridgeTest, TeleporterTokenSourceTest { | ||
using SafeERC20 for IERC20; | ||
|
||
ERC20Source public app; | ||
IERC20 public mockERC20; | ||
|
||
function setUp() public override { | ||
TeleporterTokenSourceTest.setUp(); | ||
|
||
mockERC20 = new ExampleERC20(); | ||
app = new ERC20Source( | ||
MOCK_TELEPORTER_REGISTRY_ADDRESS, | ||
MOCK_TELEPORTER_MESSENGER_ADDRESS, | ||
address(mockERC20) | ||
); | ||
erc20Bridge = app; | ||
tokenSource = app; | ||
tokenBridge = app; | ||
|
||
feeToken = mockERC20; | ||
} | ||
|
||
/** | ||
* Initialization unit tests | ||
*/ | ||
function testZeroTeleporterRegistryAddress() public { | ||
vm.expectRevert("TeleporterUpgradeable: zero teleporter registry address"); | ||
new ERC20Source(address(0), address(this), address(mockERC20)); | ||
} | ||
|
||
function testZeroTeleporterManagerAddress() public { | ||
vm.expectRevert("Ownable: new owner is the zero address"); | ||
new ERC20Source( | ||
MOCK_TELEPORTER_REGISTRY_ADDRESS, | ||
address(0), | ||
address(mockERC20) | ||
); | ||
} | ||
|
||
function testZeroFeeTokenAddress() public { | ||
vm.expectRevert(_formatErrorMessage("zero fee token address")); | ||
new ERC20Source( | ||
MOCK_TELEPORTER_REGISTRY_ADDRESS, | ||
address(this), | ||
address(0) | ||
); | ||
} | ||
|
||
function _checkExpectedWithdrawal(address recipient, uint256 amount) internal override { | ||
vm.expectCall( | ||
address(mockERC20), abi.encodeCall(IERC20.transfer, (address(recipient), amount)) | ||
); | ||
vm.expectEmit(true, true, true, true, address(mockERC20)); | ||
emit Transfer(address(app), recipient, amount); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// (c) 2024, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
// SPDX-License-Identifier: Ecosystem | ||
|
||
pragma solidity 0.8.18; | ||
|
||
import {TeleporterTokenBridgeTest} from "./TeleporterTokenBridgeTests.t.sol"; | ||
import {INativeTokenBridge} from "../src/interfaces/INativeTokenBridge.sol"; | ||
import {SendTokensInput} from "../src/interfaces/ITeleporterTokenBridge.sol"; | ||
import {IWrappedNativeToken} from "../src/interfaces/IWrappedNativeToken.sol"; | ||
|
||
abstract contract NativeTokenBridgeTest is TeleporterTokenBridgeTest { | ||
INativeTokenBridge public nativeTokenBridge; | ||
|
||
event Deposit(address indexed sender, uint256 amount); | ||
event Withdrawal(address indexed sender, uint256 amount); | ||
|
||
function testZeroSendAmount() public { | ||
vm.expectRevert(_formatErrorMessage("insufficient amount to cover fees")); | ||
_send(_createDefaultSendTokensInput(), 0); | ||
} | ||
|
||
function _send(SendTokensInput memory input, uint256 amount) internal virtual override { | ||
nativeTokenBridge.send{value: amount}(input); | ||
} | ||
|
||
function _setUpExpectedDeposit(uint256 amount) internal virtual override { | ||
vm.expectCall(address(feeToken), abi.encodeCall(IWrappedNativeToken.deposit, ())); | ||
vm.expectEmit(true, true, true, true, address(feeToken)); | ||
emit Deposit(address(nativeTokenBridge), amount); | ||
} | ||
} |
Oops, something went wrong.