Skip to content

Commit

Permalink
fixup! feat(hardhat): support post-jump commands for Stargate
Browse files Browse the repository at this point in the history
add test script
  • Loading branch information
xykota committed Sep 29, 2023
1 parent 20c2c1b commit 45ccd5a
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 16 deletions.
2 changes: 2 additions & 0 deletions packages/hardhat/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ typechain-types

# Hardhat files
cache
cache_forge/
artifacts
gas-report.txt
solidity-files-cache.json
deployments/sepolia
deployments/goerli
deployments/optimismGoerli
results.sarif
broadcast/
8 changes: 8 additions & 0 deletions packages/hardhat/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ allow_paths = ["../../node_modules"]
# See https://github.com/foundry-rs/foundry/issues/4988#issuecomment-1556331314
evm_version = 'paris'
solc_version = '0.8.19'

[rpc_endpoints]
goerli = "${GOERLI_RPC_URL}"
optimism_goerli = "${OPTIMISM_GOERLI_RPC_URL}"

[etherscan]
goerli = { key = "${ETHERSCAN_API_KEY}" }
optimism_goerli = { key = "${ETHERSCAN_API_KEY}" }
157 changes: 157 additions & 0 deletions packages/hardhat/script/jump.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import 'forge-std/console2.sol';
import 'forge-std/Script.sol';
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import {IWarpLink} from 'contracts/interfaces/IWarpLink.sol';
import {WarpLinkCommandTypes} from 'contracts/facets/WarpLink.sol';
import {IStargateRouter} from 'test/foundry/helpers/IStargateRouter.sol';
import {IAllowanceTransfer} from 'contracts/interfaces/external/IAllowanceTransfer.sol';
import {PermitParams} from 'contracts/libraries/PermitParams.sol';
import {Goerli, OptimismGoerli, Addresses} from '../test/foundry/helpers/Networks.sol';
import {PermitSignature} from 'test/foundry/helpers/PermitSignature.sol';

/**
* Bridge mock USDC from Goerli to Optimism-Goerli and invoke WarpLink on the other
* side, but with no commands.
*
* Adding commands would be even more interesting, but
* there are no actions that can be made using Statgate mock USDC.
*
* Invoke this script using:
* forge script script/jump.sol --rpc-url goerli --no-storage-caching -vvvv --broadcast
*/
contract JumpGoerli is Script, WarpLinkCommandTypes, PermitSignature {
address goerliDiamondAddr = 0x2A104392321e978495dBC91b68914eDbA3126D9c;

function setUp() public {}

function run() public {
uint256 privateKey = vm.deriveKey(vm.envString('DEV_MNEMONIC'), 1);
address user = vm.rememberKey(privateKey);

console2.log('User: %s', user);

uint48 deadline = uint48(block.timestamp) + 60 * 60 * 24 * 365;

IWarpLink.Params memory destParams = IWarpLink.Params({
tokenIn: address(0), // Unused
tokenOut: OptimismGoerli.STARGATE_MOCK_USDC_ADDR,
commands: abi.encodePacked(
(uint8)(0) // Command count
),
amountIn: 0, // Unused
amountOut: 0, // TODO
recipient: user,
partner: address(0),
feeBps: 0,
slippageBps: 0,
deadline: deadline
});

bytes memory destParamsEncoded = abi.encode(destParams);

uint256 srcAmountIn = 100 * (10 ** 6);
uint256 dstGasForCall = 500_000;
uint16 dstChainId = OptimismGoerli.STARGATE_CHAIN_ID;

bytes memory sourceCommands = bytes.concat(
abi.encodePacked(
(uint8)(1), // Command count
(uint8)(COMMAND_TYPE_JUMP_STARGATE),
(uint16)(dstChainId), // dstChainId (Goerli)
(uint8)(1), // srcPoolId (USDC)
(uint8)(1), // dstPoolId (USDC),
uint32(dstGasForCall), // dstGasForCall
uint256(destParamsEncoded.length) // NOTE: Unnecessarily large type
),
destParamsEncoded
);

(uint256 nativeWei, ) = IStargateRouter(Goerli.STARGATE_ROUTER_ADDR).quoteLayerZeroFee({
_dstChainId: dstChainId, // Goerli
_functionType: 1, // Swap remote
_toAddress: abi.encodePacked(goerliDiamondAddr),
_transferAndCallPayload: destParamsEncoded,
_lzTxParams: IStargateRouter.lzTxObj({
dstGasForCall: dstGasForCall,
dstNativeAmount: 0,
dstNativeAddr: ''
})
});

console2.log('Native fee: %s', nativeWei);

{
uint256 srcTokenInAllowance = IERC20(Goerli.STARGATE_MOCK_USDC_ADDR).allowance(
user,
address(Addresses.PERMIT2)
);

console2.log('srcTokenInAllowance: %s', srcTokenInAllowance);

if (srcTokenInAllowance < srcAmountIn) {
vm.startBroadcast(user);

SafeERC20.forceApprove(
IERC20(Goerli.STARGATE_MOCK_USDC_ADDR),
address(Addresses.PERMIT2),
type(uint256).max
);

vm.stopBroadcast();
}
}

PermitParams memory permitParams;

{
(, , uint48 nonce) = Addresses.PERMIT2.allowance(
user,
Goerli.STARGATE_MOCK_USDC_ADDR,
address(goerliDiamondAddr)
);

IAllowanceTransfer.PermitSingle memory permit = IAllowanceTransfer.PermitSingle(
IAllowanceTransfer.PermitDetails({
token: Goerli.STARGATE_MOCK_USDC_ADDR,
amount: uint160(srcAmountIn),
expiration: deadline,
nonce: nonce
}),
address(goerliDiamondAddr),
deadline
);

bytes memory sig = getPermitSignature(
permit,
privateKey,
Addresses.PERMIT2.DOMAIN_SEPARATOR()
);

permitParams = PermitParams({nonce: nonce, signature: sig});
}

vm.startBroadcast(user);

IWarpLink(goerliDiamondAddr).warpLinkEngage{value: nativeWei}(
IWarpLink.Params({
tokenIn: Goerli.STARGATE_MOCK_USDC_ADDR,
tokenOut: Goerli.STARGATE_MOCK_USDC_ADDR,
commands: sourceCommands,
amountIn: srcAmountIn,
amountOut: 0, // TODO
recipient: address(0), // Unused
partner: address(0), // Unused
feeBps: 0, // Unused
slippageBps: 0,
deadline: deadline
}),
permitParams
);

vm.stopBroadcast();
}
}
17 changes: 1 addition & 16 deletions packages/hardhat/test/foundry/WarpLink.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,7 @@ import {IAllowanceTransfer} from 'contracts/interfaces/external/IAllowanceTransf
import {IPermit2} from 'contracts/interfaces/external/IPermit2.sol';
import {PermitParams} from 'contracts/libraries/PermitParams.sol';
import {PermitSignature} from './helpers/PermitSignature.sol';

interface IStargateRouter {
struct lzTxObj {
uint256 dstGasForCall;
uint256 dstNativeAmount;
bytes dstNativeAddr;
}

function quoteLayerZeroFee(
uint16 _dstChainId,
uint8 _functionType,
bytes calldata _toAddress,
bytes calldata _transferAndCallPayload,
lzTxObj memory _lzTxParams
) external view returns (uint256, uint256);
}
import {IStargateRouter} from './helpers/IStargateRouter.sol';

contract WarpLinkTestBase is FacetTest, PermitSignature, WarpLinkCommandTypes {
event CollectedFee(
Expand Down
18 changes: 18 additions & 0 deletions packages/hardhat/test/foundry/helpers/IStargateRouter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface IStargateRouter {
struct lzTxObj {
uint256 dstGasForCall;
uint256 dstNativeAmount;
bytes dstNativeAddr;
}

function quoteLayerZeroFee(
uint16 _dstChainId,
uint8 _functionType,
bytes calldata _toAddress,
bytes calldata _transferAndCallPayload,
lzTxObj memory _lzTxParams
) external view returns (uint256, uint256);
}
11 changes: 11 additions & 0 deletions packages/hardhat/test/foundry/helpers/Networks.sol
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {IPermit2} from '../../../contracts/interfaces/external/IPermit2.sol';

Expand Down Expand Up @@ -43,6 +46,12 @@ library Optimism {
address public constant STARGATE_ROUTER_ADDR = 0x53Bf833A5d6c4ddA888F69c22C88C9f356a41614;
}

library OptimismGoerli {
address public constant STARGATE_ROUTER_ADDR = 0x95461eF0e0ecabC049a5c4a6B98Ca7B335FAF068;
address public constant STARGATE_MOCK_USDC_ADDR = 0x0CEDBAF2D0bFF895C861c5422544090EEdC653Bf;
uint16 public constant STARGATE_CHAIN_ID = 10132;
}

library Avalanche {
uint256 public constant CHAIN_ID = 43114;
address public constant STARGATE_ROUTER_ADDR = 0x45A01E4e04F14f7A4a6702c74187c5F6222033cd;
Expand All @@ -51,6 +60,8 @@ library Avalanche {
library Goerli {
uint256 public constant CHAIN_ID = 5;
address public constant STARGATE_ROUTER_ADDR = 0x7612aE2a34E5A363E137De748801FB4c86499152;
address public constant STARGATE_MOCK_USDC_ADDR = 0xDf0360Ad8C5ccf25095Aa97ee5F2785c8d848620;
uint16 public constant STARGATE_CHAIN_ID = 10121;
}

library Addresses {
Expand Down

0 comments on commit 45ccd5a

Please sign in to comment.