Skip to content

Commit

Permalink
test: improve off ramp tests
Browse files Browse the repository at this point in the history
  • Loading branch information
DhairyaSethi committed Oct 28, 2024
1 parent 47a535b commit 24b2547
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {Client} from "../../../../../libraries/Client.sol";
import {Internal} from "../../../../../libraries/Internal.sol";
import {UpgradeableLockReleaseTokenPool_Sepolia} from "./LegacyTestnetTokenPools/UpgradeableLockReleaseTokenPool_Sepolia.sol";
import {UpgradeableBurnMintTokenPool_ArbSepolia} from "./LegacyTestnetTokenPools/UpgradeableBurnMintTokenPool_ArbSepolia.sol";
import {EVM2EVMOffRamp} from "../../../../../offRamp/EVM2EVMOffRamp.sol";
import {TransparentUpgradeableProxy} from "solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol";

interface IRouter is IRouterClient, IRouterBase {
struct OffRamp {
Expand All @@ -23,6 +25,18 @@ interface IRouter is IRouterClient, IRouterBase {
function getOffRamps() external view returns (OffRamp[] memory);
}

interface IEVM2EVMOffRamp_1_2 is IAny2EVMOffRamp, ITypeAndVersion {
function executeSingleMessage(Internal.EVM2EVMMessage memory message, bytes[] memory offchainTokenData) external;
}

interface IEVM2EVMOffRamp_1_5 is IAny2EVMOffRamp, ITypeAndVersion {
function executeSingleMessage(
Internal.EVM2EVMMessage calldata message,
bytes[] calldata offchainTokenData,
uint32[] memory tokenGasOverrides
) external;
}

struct SourceTokenData {
bytes sourcePoolAddress;
bytes destTokenAddress;
Expand All @@ -32,16 +46,21 @@ struct SourceTokenData {

contract ForkBase is Test {
error CallerIsNotARampOnRouter(address caller);

event CCIPSendRequested(Internal.EVM2EVMMessage message);
event Locked(address indexed sender, uint256 amount);
event Burned(address indexed sender, uint256 amount);
event Released(address indexed sender, address indexed recipient, uint256 amount);
event Minted(address indexed sender, address indexed recipient, uint256 amount);

struct L1 {
UpgradeableLockReleaseTokenPool_Sepolia tokenPool;
IRouter router;
IERC20 token;
IEVM2AnyOnRamp EVM2EVMOnRamp1_2;
IEVM2AnyOnRamp EVM2EVMOnRamp1_5;
IAny2EVMOffRamp EVM2EVMOffRamp1_2;
IAny2EVMOffRamp EVM2EVMOffRamp1_5;
IEVM2EVMOffRamp_1_2 EVM2EVMOffRamp1_2;
IEVM2EVMOffRamp_1_5 EVM2EVMOffRamp1_5;
address proxyPool;
uint64 chainSelector;
bytes32 metadataHash;
Expand All @@ -53,8 +72,8 @@ contract ForkBase is Test {
IERC20 token;
IEVM2AnyOnRamp EVM2EVMOnRamp1_2;
IEVM2AnyOnRamp EVM2EVMOnRamp1_5;
IAny2EVMOffRamp EVM2EVMOffRamp1_2;
IAny2EVMOffRamp EVM2EVMOffRamp1_5;
IEVM2EVMOffRamp_1_2 EVM2EVMOffRamp1_2;
IEVM2EVMOffRamp_1_5 EVM2EVMOffRamp1_5;
address proxyPool;
uint64 chainSelector;
bytes32 metadataHash;
Expand All @@ -81,8 +100,8 @@ contract ForkBase is Test {
l1.token = l1.tokenPool.getToken();
l1.EVM2EVMOnRamp1_2 = IEVM2AnyOnRamp(0xe4Dd3B16E09c016402585a8aDFdB4A18f772a07e); // legacy on ramp
l1.EVM2EVMOnRamp1_5 = IEVM2AnyOnRamp(l1.router.getOnRamp(l2.chainSelector));
l1.EVM2EVMOffRamp1_2 = IAny2EVMOffRamp(0xF18896AB20a09A29e64fdEbA99FDb8EC328f43b1);
l1.EVM2EVMOffRamp1_5 = IAny2EVMOffRamp(0xD2f5edfD4561d6E7599F6c6888Bd353cAFd0c55E);
l1.EVM2EVMOffRamp1_2 = IEVM2EVMOffRamp_1_2(0xF18896AB20a09A29e64fdEbA99FDb8EC328f43b1);
l1.EVM2EVMOffRamp1_5 = IEVM2EVMOffRamp_1_5(0xD2f5edfD4561d6E7599F6c6888Bd353cAFd0c55E);
vm.prank(alice);
l1.token.approve(address(l1.router), type(uint256).max);
deal(address(l1.token), alice, 1000e18);
Expand All @@ -96,15 +115,15 @@ contract ForkBase is Test {
l2.token = l2.tokenPool.getToken();
l2.EVM2EVMOnRamp1_2 = IEVM2AnyOnRamp(0x4205E1Ca0202A248A5D42F5975A8FE56F3E302e9); // legacy on ramp
l2.EVM2EVMOnRamp1_5 = IEVM2AnyOnRamp(l2.router.getOnRamp(l1.chainSelector));
l2.EVM2EVMOffRamp1_2 = IAny2EVMOffRamp(0x1c71f141b4630EBE52d6aF4894812960abE207eB);
l2.EVM2EVMOffRamp1_5 = IAny2EVMOffRamp(0xBed6e9131916d724418C8a6FE810F727302a5c00);
l2.EVM2EVMOffRamp1_2 = IEVM2EVMOffRamp_1_2(0x1c71f141b4630EBE52d6aF4894812960abE207eB);
l2.EVM2EVMOffRamp1_5 = IEVM2EVMOffRamp_1_5(0xBed6e9131916d724418C8a6FE810F727302a5c00);
vm.prank(alice);
l2.token.approve(address(l2.router), type(uint256).max);
deal(address(l2.token), alice, 1000e18);
deal(alice, 1000e18);

l1.metadataHash = _generateMetadataHash(l1.chainSelector);
l2.metadataHash = _generateMetadataHash(l2.chainSelector);
l1.metadataHash = _generateMetadataHash(l1.chainSelector, l1.EVM2EVMOnRamp1_5);
l2.metadataHash = _generateMetadataHash(l2.chainSelector, l2.EVM2EVMOnRamp1_5);

vm.selectFork(l1.forkId);
assertEq(l1.chainSelector, 16015286601757825753);
Expand All @@ -114,8 +133,8 @@ contract ForkBase is Test {
assertEq(ITypeAndVersion(l1.proxyPool).typeAndVersion(), "LockReleaseTokenPoolAndProxy 1.5.0");
assertEq(ITypeAndVersion(address(l1.EVM2EVMOnRamp1_2)).typeAndVersion(), "EVM2EVMOnRamp 1.2.0");
assertEq(ITypeAndVersion(address(l1.EVM2EVMOnRamp1_5)).typeAndVersion(), "EVM2EVMOnRamp 1.5.0");
assertEq(ITypeAndVersion(address(l1.EVM2EVMOffRamp1_2)).typeAndVersion(), "EVM2EVMOffRamp 1.2.0");
assertEq(ITypeAndVersion(address(l1.EVM2EVMOffRamp1_5)).typeAndVersion(), "EVM2EVMOffRamp 1.5.0");
assertEq(l1.EVM2EVMOffRamp1_2.typeAndVersion(), "EVM2EVMOffRamp 1.2.0");
assertEq(l1.EVM2EVMOffRamp1_5.typeAndVersion(), "EVM2EVMOffRamp 1.5.0");
assertTrue(l1.router.isOffRamp(l2.chainSelector, address(l1.EVM2EVMOffRamp1_2)));
assertTrue(l1.router.isOffRamp(l2.chainSelector, address(l1.EVM2EVMOffRamp1_5)));

Expand All @@ -127,8 +146,8 @@ contract ForkBase is Test {
assertEq(ITypeAndVersion(l2.proxyPool).typeAndVersion(), "BurnMintTokenPoolAndProxy 1.5.0");
assertEq(ITypeAndVersion(address(l2.EVM2EVMOnRamp1_2)).typeAndVersion(), "EVM2EVMOnRamp 1.2.0");
assertEq(ITypeAndVersion(address(l2.EVM2EVMOnRamp1_5)).typeAndVersion(), "EVM2EVMOnRamp 1.5.0");
assertEq(ITypeAndVersion(address(l2.EVM2EVMOffRamp1_2)).typeAndVersion(), "EVM2EVMOffRamp 1.2.0");
assertEq(ITypeAndVersion(address(l2.EVM2EVMOffRamp1_5)).typeAndVersion(), "EVM2EVMOffRamp 1.5.0");
assertEq(l2.EVM2EVMOffRamp1_2.typeAndVersion(), "EVM2EVMOffRamp 1.2.0");
assertEq(l2.EVM2EVMOffRamp1_5.typeAndVersion(), "EVM2EVMOffRamp 1.5.0");
assertTrue(l2.router.isOffRamp(l1.chainSelector, address(l2.EVM2EVMOffRamp1_2)));
assertTrue(l2.router.isOffRamp(l1.chainSelector, address(l2.EVM2EVMOffRamp1_5)));

Expand Down Expand Up @@ -194,10 +213,10 @@ contract ForkBase is Test {
return messageEvent;
}

function _generateMetadataHash(uint64 sourceChainSelector) internal view returns (bytes32) {
function _generateMetadataHash(uint64 sourceChainSelector, IEVM2AnyOnRamp onRamp) internal view returns (bytes32) {
uint64 destChainSelector = sourceChainSelector == l1.chainSelector ? l2.chainSelector : l1.chainSelector;
address onRamp = address(sourceChainSelector == l1.chainSelector ? l1.EVM2EVMOnRamp1_5 : l2.EVM2EVMOnRamp1_5);
return keccak256(abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, sourceChainSelector, destChainSelector, onRamp));
return
keccak256(abi.encode(Internal.EVM_2_EVM_MESSAGE_HASH, sourceChainSelector, destChainSelector, address(onRamp)));
}

function _label() internal {
Expand Down Expand Up @@ -275,7 +294,7 @@ contract ForkPoolBeforeMigration is ForkBase {
l2.chainSelector = l1.tokenPool.getSupportedChains()[0];
l1.token = l1.tokenPool.getToken();
l1.EVM2EVMOnRamp1_2 = IEVM2AnyOnRamp(l1.router.getOnRamp(l2.chainSelector));
l1.EVM2EVMOffRamp1_2 = IAny2EVMOffRamp(0xdb92e73d1D630B5B7aC96840c4df0c591c7Ad23E);
l1.EVM2EVMOffRamp1_2 = IEVM2EVMOffRamp_1_2(0xdb92e73d1D630B5B7aC96840c4df0c591c7Ad23E);
vm.prank(alice);
l1.token.approve(address(l1.router), type(uint256).max);
deal(address(l1.token), alice, 1000e18);
Expand All @@ -287,7 +306,7 @@ contract ForkPoolBeforeMigration is ForkBase {
l1.chainSelector = l2.tokenPool.getSupportedChains()[0];
l2.token = l2.tokenPool.getToken();
l2.EVM2EVMOnRamp1_2 = IEVM2AnyOnRamp(l2.router.getOnRamp(l1.chainSelector));
l2.EVM2EVMOffRamp1_2 = IAny2EVMOffRamp(0xFf5e1c597c5DFfC896Ab8c7b9d876D513518c4b7);
l2.EVM2EVMOffRamp1_2 = IEVM2EVMOffRamp_1_2(0xFf5e1c597c5DFfC896Ab8c7b9d876D513518c4b7);
vm.prank(alice);
l2.token.approve(address(l2.router), type(uint256).max);
deal(address(l2.token), alice, 1000e18);
Expand All @@ -298,7 +317,7 @@ contract ForkPoolBeforeMigration is ForkBase {
assertEq(address(l1.token), 0xc4bF5CbDaBE595361438F8c6a187bDc330539c60);
assertEq(ITypeAndVersion(address(l1.router)).typeAndVersion(), "Router 1.2.0");
assertEq(ITypeAndVersion(address(l1.EVM2EVMOnRamp1_2)).typeAndVersion(), "EVM2EVMOnRamp 1.2.0");
assertEq(ITypeAndVersion(address(l1.EVM2EVMOffRamp1_2)).typeAndVersion(), "EVM2EVMOffRamp 1.2.0");
assertEq(l1.EVM2EVMOffRamp1_2.typeAndVersion(), "EVM2EVMOffRamp 1.2.0");
assertTrue(l1.router.isOffRamp(l2.chainSelector, address(l1.EVM2EVMOffRamp1_2)));
// assert only one off ramp is set
IRouter.OffRamp[] memory offRamps = l1.router.getOffRamps();
Expand All @@ -313,7 +332,7 @@ contract ForkPoolBeforeMigration is ForkBase {
assertEq(address(l2.token), 0xb13Cfa6f8B2Eed2C37fB00fF0c1A59807C585810);
assertEq(ITypeAndVersion(address(l2.router)).typeAndVersion(), "Router 1.2.0");
assertEq(ITypeAndVersion(address(l2.EVM2EVMOnRamp1_2)).typeAndVersion(), "EVM2EVMOnRamp 1.2.0");
assertEq(ITypeAndVersion(address(l2.EVM2EVMOffRamp1_2)).typeAndVersion(), "EVM2EVMOffRamp 1.2.0");
assertEq(l2.EVM2EVMOffRamp1_2.typeAndVersion(), "EVM2EVMOffRamp 1.2.0");
assertTrue(l2.router.isOffRamp(l1.chainSelector, address(l2.EVM2EVMOffRamp1_2)));
// assert only one off ramp is set
offRamps = l2.router.getOffRamps();
Expand Down Expand Up @@ -374,25 +393,58 @@ contract ForkPoolBeforeMigration is ForkBase {

function testReleaseOrMintVia1_2OffRamp() public {
uint256 amount = 10e18;
Client.EVM2AnyMessage memory message = _generateMessage(alice, 1);

// off ramp on L1
{
// build message
vm.selectFork(l2.forkId);
message.tokenAmounts[0] = Client.EVMTokenAmount({token: address(l2.token), amount: amount});
uint256 feeTokenAmount = l2.router.getFee(l1.chainSelector, message);
Internal.EVM2EVMMessage memory eventArg = _messageToEvent(
message,
l2.EVM2EVMOnRamp1_2,
feeTokenAmount,
alice,
false
);

// test off ramp
vm.selectFork(l1.forkId);

uint256 balanceBefore = l1.token.balanceOf(alice);

vm.expectEmit();
vm.expectEmit(address(l1.tokenPool));
emit Released(address(l1.EVM2EVMOffRamp1_2), alice, amount);
vm.prank(address(l1.EVM2EVMOffRamp1_2));
l1.tokenPool.releaseOrMint(abi.encode(alice), alice, amount, l2.chainSelector, "");
l1.EVM2EVMOffRamp1_2.executeSingleMessage(eventArg, new bytes[](message.tokenAmounts.length));

assertEq(l1.token.balanceOf(alice), balanceBefore + amount);
}

// off ramp on L2
{
// build message
vm.selectFork(l1.forkId);
message.tokenAmounts[0] = Client.EVMTokenAmount({token: address(l1.token), amount: amount});
uint256 feeTokenAmount = l1.router.getFee(l2.chainSelector, message);
Internal.EVM2EVMMessage memory eventArg = _messageToEvent(
message,
l1.EVM2EVMOnRamp1_2,
feeTokenAmount,
alice,
true
);

// test off ramp
vm.selectFork(l2.forkId);

uint256 balanceBefore = l2.token.balanceOf(alice);

vm.expectEmit();
vm.expectEmit(address(l2.tokenPool));
emit Minted(address(l2.EVM2EVMOffRamp1_2), alice, amount);
vm.prank(address(l2.EVM2EVMOffRamp1_2));
l2.tokenPool.releaseOrMint(abi.encode(alice), alice, amount, l1.chainSelector, "");
l2.EVM2EVMOffRamp1_2.executeSingleMessage(eventArg, new bytes[](message.tokenAmounts.length));

assertEq(l2.token.balanceOf(alice), balanceBefore + amount);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,40 +81,122 @@ contract ForkPoolUpgradeAfterMigration is ForkBase {

function testReleaseOrMintVia1_2OffRamp() public {
uint256 amount = 10e18;
Client.EVM2AnyMessage memory message = _generateMessage(alice, 1);

// off ramp on L1
{
// build message
vm.selectFork(l2.forkId);
message.tokenAmounts[0] = Client.EVMTokenAmount({token: address(l2.token), amount: amount});
uint256 feeTokenAmount = l2.router.getFee(l1.chainSelector, message);
Internal.EVM2EVMMessage memory eventArg = _messageToEvent(
message,
l2.EVM2EVMOnRamp1_5,
feeTokenAmount,
alice,
false
);

// test off ramp
vm.selectFork(l1.forkId);

uint256 balanceBefore = l1.token.balanceOf(alice);
// mock release on legacy offramp

vm.expectEmit(address(l1.tokenPool));
emit Released(address(l1.EVM2EVMOffRamp1_2), alice, amount);
vm.prank(address(l1.EVM2EVMOffRamp1_2));
l1.tokenPool.releaseOrMint(abi.encode(alice), alice, amount, l2.chainSelector, "");
l1.EVM2EVMOffRamp1_2.executeSingleMessage(eventArg, new bytes[](message.tokenAmounts.length));

assertEq(l1.token.balanceOf(alice), balanceBefore + amount);
}

// off ramp on L2
{
// build message
vm.selectFork(l1.forkId);
message.tokenAmounts[0] = Client.EVMTokenAmount({token: address(l1.token), amount: amount});
uint256 feeTokenAmount = l1.router.getFee(l2.chainSelector, message);
Internal.EVM2EVMMessage memory eventArg = _messageToEvent(
message,
l1.EVM2EVMOnRamp1_5,
feeTokenAmount,
alice,
true
);

// test off ramp
vm.selectFork(l2.forkId);

uint256 balanceBefore = l2.token.balanceOf(alice);
// mock release on legacy offramp

vm.expectEmit(address(l2.tokenPool));
emit Minted(address(l2.EVM2EVMOffRamp1_2), alice, amount);
vm.prank(address(l2.EVM2EVMOffRamp1_2));
l2.tokenPool.releaseOrMint(abi.encode(alice), alice, amount, l1.chainSelector, "");
l2.EVM2EVMOffRamp1_2.executeSingleMessage(eventArg, new bytes[](message.tokenAmounts.length));

assertEq(l2.token.balanceOf(alice), balanceBefore + amount);
}
}

function testReleaseOrMintVia1_5OffRamp() public {
uint256 amount = 10e18;
Client.EVM2AnyMessage memory message = _generateMessage(alice, 1);

// off ramp on L1
{
// build message
vm.selectFork(l2.forkId);
message.tokenAmounts[0] = Client.EVMTokenAmount({token: address(l2.token), amount: amount});
uint256 feeTokenAmount = l2.router.getFee(l1.chainSelector, message);
Internal.EVM2EVMMessage memory eventArg = _messageToEvent(
message,
l2.EVM2EVMOnRamp1_5,
feeTokenAmount,
alice,
false
);

// test off ramp
vm.selectFork(l1.forkId);

uint256 balanceBefore = l1.token.balanceOf(alice);
// mock release on legacy offramp

vm.expectEmit(address(l1.tokenPool));
emit Released(address(l1.proxyPool), alice, amount);
vm.expectEmit(address(l1.proxyPool));
emit Released(address(l1.EVM2EVMOffRamp1_5), alice, amount);
vm.prank(address(l1.EVM2EVMOffRamp1_5));
l1.tokenPool.releaseOrMint(abi.encode(alice), alice, amount, l2.chainSelector, "");
l1.EVM2EVMOffRamp1_5.executeSingleMessage(eventArg, new bytes[](message.tokenAmounts.length), new uint32[](0));

assertEq(l1.token.balanceOf(alice), balanceBefore + amount);
}

// off ramp on L2
{
// build message
vm.selectFork(l1.forkId);
message.tokenAmounts[0] = Client.EVMTokenAmount({token: address(l1.token), amount: amount});
uint256 feeTokenAmount = l1.router.getFee(l2.chainSelector, message);
Internal.EVM2EVMMessage memory eventArg = _messageToEvent(
message,
l1.EVM2EVMOnRamp1_5,
feeTokenAmount,
alice,
true
);

// test off ramp
vm.selectFork(l2.forkId);

uint256 balanceBefore = l2.token.balanceOf(alice);
// mock release on legacy offramp

vm.expectEmit(address(l2.tokenPool));
emit Minted(address(l2.proxyPool), alice, amount);
vm.expectEmit(address(l2.proxyPool));
emit Minted(address(l2.EVM2EVMOffRamp1_5), alice, amount);
vm.prank(address(l2.EVM2EVMOffRamp1_5));
l2.tokenPool.releaseOrMint(abi.encode(alice), alice, amount, l1.chainSelector, "");
l2.EVM2EVMOffRamp1_5.executeSingleMessage(eventArg, new bytes[](message.tokenAmounts.length), new uint32[](0));

assertEq(l2.token.balanceOf(alice), balanceBefore + amount);
}
}
Expand Down

0 comments on commit 24b2547

Please sign in to comment.