mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
commit
a19ed504e5
17
contracts/arbitrum/connectors/hop/events.sol
Normal file
17
contracts/arbitrum/connectors/hop/events.sol
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
contract Events {
|
||||||
|
event LogBridge(
|
||||||
|
address token,
|
||||||
|
uint256 chainId,
|
||||||
|
address recipient,
|
||||||
|
uint256 amount,
|
||||||
|
uint256 bonderFee,
|
||||||
|
uint256 amountOutMin,
|
||||||
|
uint256 deadline,
|
||||||
|
uint256 destinationAmountOutMin,
|
||||||
|
uint256 destinationDeadline,
|
||||||
|
uint256 getId
|
||||||
|
);
|
||||||
|
}
|
||||||
52
contracts/arbitrum/connectors/hop/helpers.sol
Normal file
52
contracts/arbitrum/connectors/hop/helpers.sol
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
import { TokenInterface } from "../../common/interfaces.sol";
|
||||||
|
import { DSMath } from "../../common/math.sol";
|
||||||
|
import { Basic } from "../../common/basic.sol";
|
||||||
|
import "./interface.sol";
|
||||||
|
|
||||||
|
contract Helpers is DSMath, Basic {
|
||||||
|
/**
|
||||||
|
* @param token The address of token to be bridged.(For USDC: 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174)
|
||||||
|
* @param targetChainId The Id of the destination chain.(For MAINNET : 1)
|
||||||
|
* @param router The address of hop router.
|
||||||
|
* @param recipient The address to recieve the token on destination chain.
|
||||||
|
* @param amount The total amount sent by user (Includes bonder fee, destination chain Tx cost).
|
||||||
|
* @param bonderFee The fee to be recieved by bonder at destination chain.
|
||||||
|
* @param sourceAmountOutMin minimum amount of token out for swap on source chain.
|
||||||
|
* @param sourceDeadline The deadline for the source chain transaction (Recommended - Date.now() + 604800 (1 week))
|
||||||
|
* @param destinationAmountOutMin minimum amount of token out for bridge on target chain, zero for L1 bridging
|
||||||
|
* @param destinationDeadline The deadline for the target chain transaction (Recommended - Date.now() + 604800 (1 week)), zero for L1 bridging
|
||||||
|
*/
|
||||||
|
struct BridgeParams {
|
||||||
|
address token;
|
||||||
|
address router;
|
||||||
|
address recipient;
|
||||||
|
uint256 targetChainId;
|
||||||
|
uint256 amount;
|
||||||
|
uint256 bonderFee;
|
||||||
|
uint256 sourceAmountOutMin;
|
||||||
|
uint256 sourceDeadline;
|
||||||
|
uint256 destinationAmountOutMin;
|
||||||
|
uint256 destinationDeadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _swapAndSend(BridgeParams memory params) internal {
|
||||||
|
IHopRouter router = IHopRouter(params.router);
|
||||||
|
|
||||||
|
TokenInterface tokenContract = TokenInterface(params.token);
|
||||||
|
approve(tokenContract, params.router, params.amount);
|
||||||
|
|
||||||
|
router.swapAndSend(
|
||||||
|
params.targetChainId,
|
||||||
|
params.recipient,
|
||||||
|
params.amount,
|
||||||
|
params.bonderFee,
|
||||||
|
params.sourceAmountOutMin,
|
||||||
|
params.sourceDeadline,
|
||||||
|
params.destinationAmountOutMin,
|
||||||
|
params.destinationDeadline
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
contracts/arbitrum/connectors/hop/interface.sol
Normal file
17
contracts/arbitrum/connectors/hop/interface.sol
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
import { TokenInterface } from "../../common/interfaces.sol";
|
||||||
|
|
||||||
|
interface IHopRouter {
|
||||||
|
function swapAndSend(
|
||||||
|
uint256 chainId,
|
||||||
|
address recipient,
|
||||||
|
uint256 amount,
|
||||||
|
uint256 bonderFee,
|
||||||
|
uint256 amountOutMin,
|
||||||
|
uint256 deadline,
|
||||||
|
uint256 destinationAmountOutMin,
|
||||||
|
uint256 destinationDeadline
|
||||||
|
) external;
|
||||||
|
}
|
||||||
77
contracts/arbitrum/connectors/hop/main.sol
Normal file
77
contracts/arbitrum/connectors/hop/main.sol
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title Hop.
|
||||||
|
* @dev Cross chain Bridge.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { TokenInterface, MemoryInterface } from "../../common/interfaces.sol";
|
||||||
|
import { Stores } from "../../common/stores.sol";
|
||||||
|
import "./interface.sol";
|
||||||
|
import "./helpers.sol";
|
||||||
|
import "./events.sol";
|
||||||
|
|
||||||
|
abstract contract Resolver is Helpers {
|
||||||
|
/**
|
||||||
|
* @dev Bridge Token.
|
||||||
|
* @notice Bridge Token on HOP.
|
||||||
|
* @param params BridgeParams struct for bridging
|
||||||
|
* @param getId ID to retrieve amount from last spell.
|
||||||
|
*/
|
||||||
|
function bridge(BridgeParams memory params, uint256 getId)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (string memory _eventName, bytes memory _eventParam)
|
||||||
|
{
|
||||||
|
if (params.targetChainId == 1) {
|
||||||
|
require(
|
||||||
|
params.destinationAmountOutMin == 0,
|
||||||
|
"destinationAmountOutMin != 0, sending to L1"
|
||||||
|
);
|
||||||
|
require(
|
||||||
|
params.destinationDeadline == 0,
|
||||||
|
"destinationDeadline != 0, sending to L1"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
params.amount = getUint(getId, params.amount);
|
||||||
|
|
||||||
|
bool isEth = params.token == ethAddr;
|
||||||
|
params.token = params.token == ethAddr ? wethAddr : params.token;
|
||||||
|
|
||||||
|
TokenInterface tokenContract = TokenInterface(params.token);
|
||||||
|
|
||||||
|
if (isEth) {
|
||||||
|
params.amount = params.amount == uint256(-1)
|
||||||
|
? address(this).balance
|
||||||
|
: params.amount;
|
||||||
|
convertEthToWeth(isEth, tokenContract, params.amount);
|
||||||
|
} else {
|
||||||
|
params.amount = params.amount == uint256(-1)
|
||||||
|
? tokenContract.balanceOf(address(this))
|
||||||
|
: params.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
_swapAndSend(params);
|
||||||
|
|
||||||
|
_eventName = "LogBridge(address,uint256,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)";
|
||||||
|
_eventParam = abi.encode(
|
||||||
|
params.token,
|
||||||
|
params.targetChainId,
|
||||||
|
params.recipient,
|
||||||
|
params.amount,
|
||||||
|
params.bonderFee,
|
||||||
|
params.sourceAmountOutMin,
|
||||||
|
params.sourceDeadline,
|
||||||
|
params.destinationAmountOutMin,
|
||||||
|
params.destinationDeadline,
|
||||||
|
getId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ConnectV2HopArbitrum is Resolver {
|
||||||
|
string public constant name = "Hop-v1.0";
|
||||||
|
}
|
||||||
14
contracts/mainnet/connectors/hop/events.sol
Normal file
14
contracts/mainnet/connectors/hop/events.sol
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
contract Events {
|
||||||
|
event LogBridge(
|
||||||
|
address token,
|
||||||
|
uint256 chainId,
|
||||||
|
address recipient,
|
||||||
|
uint256 amount,
|
||||||
|
uint256 amountOutMin,
|
||||||
|
uint256 deadline,
|
||||||
|
uint256 getId
|
||||||
|
);
|
||||||
|
}
|
||||||
45
contracts/mainnet/connectors/hop/helpers.sol
Normal file
45
contracts/mainnet/connectors/hop/helpers.sol
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
import { TokenInterface } from "../../common/interfaces.sol";
|
||||||
|
import { DSMath } from "../../common/math.sol";
|
||||||
|
import { Basic } from "../../common/basic.sol";
|
||||||
|
import "./interface.sol";
|
||||||
|
|
||||||
|
contract Helpers is DSMath, Basic {
|
||||||
|
/**
|
||||||
|
* @param token The address of token to be bridged.(For USDC: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)
|
||||||
|
* @param hopRouter The address of hop l1Bridge.
|
||||||
|
* @param chainId The Id of the destination chain.(For POLYGON : 137)
|
||||||
|
* @param recipient The address to recieve the token on destination chain.
|
||||||
|
* @param amount The total amount sent by user (Includes bonder fee, destination chain Tx cost).
|
||||||
|
* @param amountOutMin minimum amount of token out for swap
|
||||||
|
* @param deadline The deadline for the transaction (Recommended - Date.now() + 604800 (1 week))
|
||||||
|
*/
|
||||||
|
struct BridgeParams {
|
||||||
|
address token;
|
||||||
|
address recipient;
|
||||||
|
address router;
|
||||||
|
uint256 targetChainId;
|
||||||
|
uint256 amount;
|
||||||
|
uint256 destinationAmountOutMin;
|
||||||
|
uint256 destinationDeadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _sendToL2(BridgeParams memory params) internal {
|
||||||
|
IHopRouter router = IHopRouter(params.router);
|
||||||
|
|
||||||
|
TokenInterface tokenContract = TokenInterface(params.token);
|
||||||
|
approve(tokenContract, params.router, params.amount);
|
||||||
|
|
||||||
|
router.sendToL2(
|
||||||
|
params.targetChainId,
|
||||||
|
params.recipient,
|
||||||
|
params.amount,
|
||||||
|
params.destinationAmountOutMin,
|
||||||
|
params.destinationDeadline,
|
||||||
|
address(0), // relayer address
|
||||||
|
0 // relayer fee
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
contracts/mainnet/connectors/hop/interface.sol
Normal file
16
contracts/mainnet/connectors/hop/interface.sol
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
import { TokenInterface } from "../../common/interfaces.sol";
|
||||||
|
|
||||||
|
interface IHopRouter {
|
||||||
|
function sendToL2(
|
||||||
|
uint256 chainId,
|
||||||
|
address recipient,
|
||||||
|
uint256 amount,
|
||||||
|
uint256 amountOutMin,
|
||||||
|
uint256 deadline,
|
||||||
|
address relayer,
|
||||||
|
uint256 relayerFee
|
||||||
|
) external;
|
||||||
|
}
|
||||||
63
contracts/mainnet/connectors/hop/main.sol
Normal file
63
contracts/mainnet/connectors/hop/main.sol
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title Hop.
|
||||||
|
* @dev Cross chain Bridge.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { TokenInterface, MemoryInterface } from "../../common/interfaces.sol";
|
||||||
|
import { Stores } from "../../common/stores.sol";
|
||||||
|
import "./interface.sol";
|
||||||
|
import "./helpers.sol";
|
||||||
|
import "./events.sol";
|
||||||
|
|
||||||
|
abstract contract Resolver is Helpers {
|
||||||
|
/**
|
||||||
|
* @dev Bridge Token.
|
||||||
|
* @notice Bridge Token on HOP.
|
||||||
|
* @param params BridgeParams struct for bridging
|
||||||
|
* @param getId ID to retrieve amount from last spell.
|
||||||
|
*/
|
||||||
|
function bridge(BridgeParams memory params, uint256 getId)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (string memory _eventName, bytes memory _eventParam)
|
||||||
|
{
|
||||||
|
params.amount = getUint(getId, params.amount);
|
||||||
|
|
||||||
|
bool isEth = params.token == ethAddr;
|
||||||
|
params.token = params.token == ethAddr ? wethAddr : params.token;
|
||||||
|
|
||||||
|
TokenInterface tokenContract = TokenInterface(params.token);
|
||||||
|
|
||||||
|
if (isEth) {
|
||||||
|
params.amount = params.amount == uint256(-1)
|
||||||
|
? address(this).balance
|
||||||
|
: params.amount;
|
||||||
|
convertEthToWeth(isEth, tokenContract, params.amount);
|
||||||
|
} else {
|
||||||
|
params.amount = params.amount == uint256(-1)
|
||||||
|
? tokenContract.balanceOf(address(this))
|
||||||
|
: params.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
_sendToL2(params);
|
||||||
|
|
||||||
|
_eventName = "LogBridge(address,uint256,address,uint256,uint256,uint256,uint256)";
|
||||||
|
_eventParam = abi.encode(
|
||||||
|
params.token,
|
||||||
|
params.targetChainId,
|
||||||
|
params.recipient,
|
||||||
|
params.amount,
|
||||||
|
params.destinationAmountOutMin,
|
||||||
|
params.destinationDeadline,
|
||||||
|
getId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ConnectV2Hop is Resolver {
|
||||||
|
string public constant name = "Hop-v1.0";
|
||||||
|
}
|
||||||
17
contracts/optimism/connectors/hop/events.sol
Normal file
17
contracts/optimism/connectors/hop/events.sol
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
contract Events {
|
||||||
|
event LogBridge(
|
||||||
|
address token,
|
||||||
|
uint256 chainId,
|
||||||
|
address recipient,
|
||||||
|
uint256 amount,
|
||||||
|
uint256 bonderFee,
|
||||||
|
uint256 amountOutMin,
|
||||||
|
uint256 deadline,
|
||||||
|
uint256 destinationAmountOutMin,
|
||||||
|
uint256 destinationDeadline,
|
||||||
|
uint256 getId
|
||||||
|
);
|
||||||
|
}
|
||||||
52
contracts/optimism/connectors/hop/helpers.sol
Normal file
52
contracts/optimism/connectors/hop/helpers.sol
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
import { TokenInterface } from "../../common/interfaces.sol";
|
||||||
|
import { DSMath } from "../../common/math.sol";
|
||||||
|
import { Basic } from "../../common/basic.sol";
|
||||||
|
import "./interface.sol";
|
||||||
|
|
||||||
|
contract Helpers is DSMath, Basic {
|
||||||
|
/**
|
||||||
|
* @param token The address of token to be bridged.(For USDC: 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174)
|
||||||
|
* @param targetChainId The Id of the destination chain.(For MAINNET : 1)
|
||||||
|
* @param router The address of hop router.
|
||||||
|
* @param recipient The address to recieve the token on destination chain.
|
||||||
|
* @param amount The total amount sent by user (Includes bonder fee, destination chain Tx cost).
|
||||||
|
* @param bonderFee The fee to be recieved by bonder at destination chain.
|
||||||
|
* @param sourceAmountOutMin minimum amount of token out for swap on source chain.
|
||||||
|
* @param sourceDeadline The deadline for the source chain transaction (Recommended - Date.now() + 604800 (1 week))
|
||||||
|
* @param destinationAmountOutMin minimum amount of token out for bridge on target chain, zero for L1 bridging
|
||||||
|
* @param destinationDeadline The deadline for the target chain transaction (Recommended - Date.now() + 604800 (1 week)), zero for L1 bridging
|
||||||
|
*/
|
||||||
|
struct BridgeParams {
|
||||||
|
address token;
|
||||||
|
address router;
|
||||||
|
address recipient;
|
||||||
|
uint256 targetChainId;
|
||||||
|
uint256 amount;
|
||||||
|
uint256 bonderFee;
|
||||||
|
uint256 sourceAmountOutMin;
|
||||||
|
uint256 sourceDeadline;
|
||||||
|
uint256 destinationAmountOutMin;
|
||||||
|
uint256 destinationDeadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _swapAndSend(BridgeParams memory params) internal {
|
||||||
|
IHopRouter router = IHopRouter(params.router);
|
||||||
|
|
||||||
|
TokenInterface tokenContract = TokenInterface(params.token);
|
||||||
|
approve(tokenContract, params.router, params.amount);
|
||||||
|
|
||||||
|
router.swapAndSend(
|
||||||
|
params.targetChainId,
|
||||||
|
params.recipient,
|
||||||
|
params.amount,
|
||||||
|
params.bonderFee,
|
||||||
|
params.sourceAmountOutMin,
|
||||||
|
params.sourceDeadline,
|
||||||
|
params.destinationAmountOutMin,
|
||||||
|
params.destinationDeadline
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
contracts/optimism/connectors/hop/interface.sol
Normal file
17
contracts/optimism/connectors/hop/interface.sol
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
import { TokenInterface } from "../../common/interfaces.sol";
|
||||||
|
|
||||||
|
interface IHopRouter {
|
||||||
|
function swapAndSend(
|
||||||
|
uint256 chainId,
|
||||||
|
address recipient,
|
||||||
|
uint256 amount,
|
||||||
|
uint256 bonderFee,
|
||||||
|
uint256 amountOutMin,
|
||||||
|
uint256 deadline,
|
||||||
|
uint256 destinationAmountOutMin,
|
||||||
|
uint256 destinationDeadline
|
||||||
|
) external;
|
||||||
|
}
|
||||||
77
contracts/optimism/connectors/hop/main.sol
Normal file
77
contracts/optimism/connectors/hop/main.sol
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title Hop.
|
||||||
|
* @dev Cross chain Bridge.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { TokenInterface, MemoryInterface } from "../../common/interfaces.sol";
|
||||||
|
import { Stores } from "../../common/stores.sol";
|
||||||
|
import "./interface.sol";
|
||||||
|
import "./helpers.sol";
|
||||||
|
import "./events.sol";
|
||||||
|
|
||||||
|
abstract contract Resolver is Helpers {
|
||||||
|
/**
|
||||||
|
* @dev Bridge Token.
|
||||||
|
* @notice Bridge Token on HOP.
|
||||||
|
* @param params BridgeParams struct for bridging
|
||||||
|
* @param getId ID to retrieve amount from last spell.
|
||||||
|
*/
|
||||||
|
function bridge(BridgeParams memory params, uint256 getId)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (string memory _eventName, bytes memory _eventParam)
|
||||||
|
{
|
||||||
|
if (params.targetChainId == 1) {
|
||||||
|
require(
|
||||||
|
params.destinationAmountOutMin == 0,
|
||||||
|
"destinationAmountOutMin != 0, sending to L1"
|
||||||
|
);
|
||||||
|
require(
|
||||||
|
params.destinationDeadline == 0,
|
||||||
|
"destinationDeadline != 0, sending to L1"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
params.amount = getUint(getId, params.amount);
|
||||||
|
|
||||||
|
bool isEth = params.token == ethAddr;
|
||||||
|
params.token = params.token == ethAddr ? wethAddr : params.token;
|
||||||
|
|
||||||
|
TokenInterface tokenContract = TokenInterface(params.token);
|
||||||
|
|
||||||
|
if (isEth) {
|
||||||
|
params.amount = params.amount == uint256(-1)
|
||||||
|
? address(this).balance
|
||||||
|
: params.amount;
|
||||||
|
convertEthToWeth(isEth, tokenContract, params.amount);
|
||||||
|
} else {
|
||||||
|
params.amount = params.amount == uint256(-1)
|
||||||
|
? tokenContract.balanceOf(address(this))
|
||||||
|
: params.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
_swapAndSend(params);
|
||||||
|
|
||||||
|
_eventName = "LogBridge(address,uint256,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)";
|
||||||
|
_eventParam = abi.encode(
|
||||||
|
params.token,
|
||||||
|
params.targetChainId,
|
||||||
|
params.recipient,
|
||||||
|
params.amount,
|
||||||
|
params.bonderFee,
|
||||||
|
params.sourceAmountOutMin,
|
||||||
|
params.sourceDeadline,
|
||||||
|
params.destinationAmountOutMin,
|
||||||
|
params.destinationDeadline,
|
||||||
|
getId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ConnectV2HopOptimism is Resolver {
|
||||||
|
string public constant name = "Hop-v1.0";
|
||||||
|
}
|
||||||
17
contracts/polygon/connectors/hop/events.sol
Normal file
17
contracts/polygon/connectors/hop/events.sol
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
contract Events {
|
||||||
|
event LogBridge(
|
||||||
|
address token,
|
||||||
|
uint256 chainId,
|
||||||
|
address recipient,
|
||||||
|
uint256 amount,
|
||||||
|
uint256 bonderFee,
|
||||||
|
uint256 amountOutMin,
|
||||||
|
uint256 deadline,
|
||||||
|
uint256 destinationAmountOutMin,
|
||||||
|
uint256 destinationDeadline,
|
||||||
|
uint256 getId
|
||||||
|
);
|
||||||
|
}
|
||||||
52
contracts/polygon/connectors/hop/helpers.sol
Normal file
52
contracts/polygon/connectors/hop/helpers.sol
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
import { TokenInterface } from "../../common/interfaces.sol";
|
||||||
|
import { DSMath } from "../../common/math.sol";
|
||||||
|
import { Basic } from "../../common/basic.sol";
|
||||||
|
import "./interface.sol";
|
||||||
|
|
||||||
|
contract Helpers is DSMath, Basic {
|
||||||
|
/**
|
||||||
|
* @param token The address of token to be bridged.(For USDC: 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174)
|
||||||
|
* @param targetChainId The Id of the destination chain.(For MAINNET : 1)
|
||||||
|
* @param router The address of hop router.
|
||||||
|
* @param recipient The address to recieve the token on destination chain.
|
||||||
|
* @param amount The total amount sent by user (Includes bonder fee, destination chain Tx cost).
|
||||||
|
* @param bonderFee The fee to be recieved by bonder at destination chain.
|
||||||
|
* @param sourceAmountOutMin minimum amount of token out for swap on source chain.
|
||||||
|
* @param sourceDeadline The deadline for the source chain transaction (Recommended - Date.now() + 604800 (1 week))
|
||||||
|
* @param destinationAmountOutMin minimum amount of token out for bridge on target chain, zero for L1 bridging
|
||||||
|
* @param destinationDeadline The deadline for the target chain transaction (Recommended - Date.now() + 604800 (1 week)), zero for L1 bridging
|
||||||
|
*/
|
||||||
|
struct BridgeParams {
|
||||||
|
address token;
|
||||||
|
address router;
|
||||||
|
address recipient;
|
||||||
|
uint256 targetChainId;
|
||||||
|
uint256 amount;
|
||||||
|
uint256 bonderFee;
|
||||||
|
uint256 sourceAmountOutMin;
|
||||||
|
uint256 sourceDeadline;
|
||||||
|
uint256 destinationAmountOutMin;
|
||||||
|
uint256 destinationDeadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _swapAndSend(BridgeParams memory params) internal {
|
||||||
|
IHopRouter router = IHopRouter(params.router);
|
||||||
|
|
||||||
|
TokenInterface tokenContract = TokenInterface(params.token);
|
||||||
|
approve(tokenContract, params.router, params.amount);
|
||||||
|
|
||||||
|
router.swapAndSend(
|
||||||
|
params.targetChainId,
|
||||||
|
params.recipient,
|
||||||
|
params.amount,
|
||||||
|
params.bonderFee,
|
||||||
|
params.sourceAmountOutMin,
|
||||||
|
params.sourceDeadline,
|
||||||
|
params.destinationAmountOutMin,
|
||||||
|
params.destinationDeadline
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
contracts/polygon/connectors/hop/interface.sol
Normal file
17
contracts/polygon/connectors/hop/interface.sol
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
|
||||||
|
import { TokenInterface } from "../../common/interfaces.sol";
|
||||||
|
|
||||||
|
interface IHopRouter {
|
||||||
|
function swapAndSend(
|
||||||
|
uint256 chainId,
|
||||||
|
address recipient,
|
||||||
|
uint256 amount,
|
||||||
|
uint256 bonderFee,
|
||||||
|
uint256 amountOutMin,
|
||||||
|
uint256 deadline,
|
||||||
|
uint256 destinationAmountOutMin,
|
||||||
|
uint256 destinationDeadline
|
||||||
|
) external;
|
||||||
|
}
|
||||||
77
contracts/polygon/connectors/hop/main.sol
Normal file
77
contracts/polygon/connectors/hop/main.sol
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
//SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.7.0;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title Hop.
|
||||||
|
* @dev Cross chain Bridge.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { TokenInterface, MemoryInterface } from "../../common/interfaces.sol";
|
||||||
|
import { Stores } from "../../common/stores.sol";
|
||||||
|
import "./interface.sol";
|
||||||
|
import "./helpers.sol";
|
||||||
|
import "./events.sol";
|
||||||
|
|
||||||
|
abstract contract Resolver is Helpers {
|
||||||
|
/**
|
||||||
|
* @dev Bridge Token.
|
||||||
|
* @notice Bridge Token on HOP.
|
||||||
|
* @param params BridgeParams struct for bridging
|
||||||
|
* @param getId ID to retrieve amount from last spell.
|
||||||
|
*/
|
||||||
|
function bridge(BridgeParams memory params, uint256 getId)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (string memory _eventName, bytes memory _eventParam)
|
||||||
|
{
|
||||||
|
if (params.targetChainId == 1) {
|
||||||
|
require(
|
||||||
|
params.destinationAmountOutMin == 0,
|
||||||
|
"destinationAmountOutMin != 0, sending to L1"
|
||||||
|
);
|
||||||
|
require(
|
||||||
|
params.destinationDeadline == 0,
|
||||||
|
"destinationDeadline != 0, sending to L1"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
params.amount = getUint(getId, params.amount);
|
||||||
|
|
||||||
|
bool isMatic = params.token == maticAddr;
|
||||||
|
params.token = params.token == maticAddr ? wmaticAddr : params.token;
|
||||||
|
|
||||||
|
TokenInterface tokenContract = TokenInterface(params.token);
|
||||||
|
|
||||||
|
if (isMatic) {
|
||||||
|
params.amount = params.amount == uint256(-1)
|
||||||
|
? address(this).balance
|
||||||
|
: params.amount;
|
||||||
|
convertMaticToWmatic(isMatic, tokenContract, params.amount);
|
||||||
|
} else {
|
||||||
|
params.amount = params.amount == uint256(-1)
|
||||||
|
? tokenContract.balanceOf(address(this))
|
||||||
|
: params.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
_swapAndSend(params);
|
||||||
|
|
||||||
|
_eventName = "LogBridge(address,uint256,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)";
|
||||||
|
_eventParam = abi.encode(
|
||||||
|
params.token,
|
||||||
|
params.targetChainId,
|
||||||
|
params.recipient,
|
||||||
|
params.amount,
|
||||||
|
params.bonderFee,
|
||||||
|
params.sourceAmountOutMin,
|
||||||
|
params.sourceDeadline,
|
||||||
|
params.destinationAmountOutMin,
|
||||||
|
params.destinationDeadline,
|
||||||
|
getId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ConnectV2HopPolygon is Resolver {
|
||||||
|
string public constant name = "Hop-v1.0";
|
||||||
|
}
|
||||||
240
test/polygon/hop/hop.test.ts
Normal file
240
test/polygon/hop/hop.test.ts
Normal file
|
|
@ -0,0 +1,240 @@
|
||||||
|
import { expect } from "chai";
|
||||||
|
import hre from "hardhat";
|
||||||
|
const { waffle, ethers } = hre;
|
||||||
|
const { provider } = waffle;
|
||||||
|
|
||||||
|
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
|
||||||
|
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
|
||||||
|
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
|
||||||
|
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
|
||||||
|
import { addLiquidity } from "../../../scripts/tests/addLiquidity";
|
||||||
|
import { addresses } from "../../../scripts/tests/polygon/addresses";
|
||||||
|
import { abis } from "../../../scripts/constant/abis";
|
||||||
|
import { ConnectV2HopPolygon__factory } from "../../../typechain";
|
||||||
|
import { Signer, Contract } from "ethers";
|
||||||
|
import BigNumber from "bignumber.js";
|
||||||
|
|
||||||
|
describe("Hop Connector", function () {
|
||||||
|
const connectorName = "HOP-A";
|
||||||
|
|
||||||
|
let dsaWallet0: Contract;
|
||||||
|
let masterSigner: Signer;
|
||||||
|
let instaConnectorsV2: Contract;
|
||||||
|
let connector: Contract;
|
||||||
|
let latestBlock: any;
|
||||||
|
|
||||||
|
const wallets = provider.getWallets();
|
||||||
|
const [wallet0, wallet1, wallet2, wallet3] = wallets;
|
||||||
|
|
||||||
|
const saddleSwapABI = [
|
||||||
|
{
|
||||||
|
inputs: [{ internalType: "address", name: "tokenAddress", type: "address" }],
|
||||||
|
name: "getTokenIndex",
|
||||||
|
outputs: [{ internalType: "uint8", name: "", type: "uint8" }],
|
||||||
|
stateMutability: "view",
|
||||||
|
type: "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputs: [
|
||||||
|
{ internalType: "uint8", name: "tokenIndexFrom", type: "uint8" },
|
||||||
|
{ internalType: "uint8", name: "tokenIndexTo", type: "uint8" },
|
||||||
|
{ internalType: "uint256", name: "dx", type: "uint256" }
|
||||||
|
],
|
||||||
|
name: "calculateSwap",
|
||||||
|
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
||||||
|
stateMutability: "view",
|
||||||
|
type: "function"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const l2BridgeABI = [
|
||||||
|
{
|
||||||
|
anonymous: false,
|
||||||
|
inputs: [
|
||||||
|
{ indexed: true, internalType: "bytes32", name: "transferId", type: "bytes32" },
|
||||||
|
{ indexed: true, internalType: "uint256", name: "chainId", type: "uint256" },
|
||||||
|
{ indexed: true, internalType: "address", name: "recipient", type: "address" },
|
||||||
|
{ indexed: false, internalType: "uint256", name: "amount", type: "uint256" },
|
||||||
|
{ indexed: false, internalType: "bytes32", name: "transferNonce", type: "bytes32" },
|
||||||
|
{ indexed: false, internalType: "uint256", name: "bonderFee", type: "uint256" },
|
||||||
|
{ indexed: false, internalType: "uint256", name: "index", type: "uint256" },
|
||||||
|
{ indexed: false, internalType: "uint256", name: "amountOutMin", type: "uint256" },
|
||||||
|
{ indexed: false, internalType: "uint256", name: "deadline", type: "uint256" }
|
||||||
|
],
|
||||||
|
name: "TransferSent",
|
||||||
|
type: "event"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const DAI_ADDR = "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063";
|
||||||
|
const hDai = "0xb8901acB165ed027E32754E0FFe830802919727f";
|
||||||
|
const l2AmmWrapper = "0x28529fec439cfF6d7D1D5917e956dEE62Cd3BE5c";
|
||||||
|
const l2Bridge = "0xEcf268Be00308980B5b3fcd0975D47C4C8e1382a";
|
||||||
|
const saddleSwap = "0x25FB92E505F752F730cAD0Bd4fa17ecE4A384266";
|
||||||
|
const saddleSwapInstance = new ethers.Contract(saddleSwap, saddleSwapABI);
|
||||||
|
|
||||||
|
const token = new ethers.Contract(DAI_ADDR, abis.basic.erc20);
|
||||||
|
const l2BridgeInstance = new ethers.Contract(l2Bridge, l2BridgeABI);
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
await hre.network.provider.request({
|
||||||
|
method: "hardhat_reset",
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
forking: {
|
||||||
|
// @ts-ignore
|
||||||
|
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
|
||||||
|
blockNumber: 27054896
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
masterSigner = await getMasterSigner();
|
||||||
|
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
|
||||||
|
connector = await deployAndEnableConnector({
|
||||||
|
connectorName,
|
||||||
|
contractArtifact: ConnectV2HopPolygon__factory,
|
||||||
|
signer: masterSigner,
|
||||||
|
connectors: instaConnectorsV2
|
||||||
|
});
|
||||||
|
console.log("Connector address", connector.address);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should have contracts deployed.", async function () {
|
||||||
|
expect(!!instaConnectorsV2.address).to.be.true;
|
||||||
|
expect(!!connector.address).to.be.true;
|
||||||
|
expect(!!(await masterSigner.getAddress())).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("DSA wallet setup", function () {
|
||||||
|
it("Should build DSA v2", async function () {
|
||||||
|
dsaWallet0 = await buildDSAv2(wallet0.address);
|
||||||
|
expect(!!dsaWallet0.address).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Deposit MATIC & DAI into DSA wallet", async function () {
|
||||||
|
await wallet0.sendTransaction({
|
||||||
|
to: dsaWallet0.address,
|
||||||
|
value: ethers.utils.parseEther("10")
|
||||||
|
});
|
||||||
|
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
|
||||||
|
|
||||||
|
await addLiquidity("dai", dsaWallet0.address, ethers.utils.parseEther("10000"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Main", function () {
|
||||||
|
it("should migrate from L2 to L1", async function () {
|
||||||
|
const amount = ethers.utils.parseEther("10");
|
||||||
|
const bonderFee = new BigNumber(100 * 1e9)
|
||||||
|
.multipliedBy(150000)
|
||||||
|
.multipliedBy(1.5)
|
||||||
|
.plus(new BigNumber(amount.toString()).multipliedBy(0.18));
|
||||||
|
const deadline = Date.now() + 604800;
|
||||||
|
const getId = "0";
|
||||||
|
|
||||||
|
await token.connect(wallet0).approve(l2AmmWrapper, amount.toString());
|
||||||
|
|
||||||
|
const hDaiIdx = await saddleSwapInstance.connect(wallet0).getTokenIndex(hDai);
|
||||||
|
const daiIdx = await saddleSwapInstance.connect(wallet0).getTokenIndex(DAI_ADDR);
|
||||||
|
|
||||||
|
let amountOutMin = await saddleSwapInstance.connect(wallet0).calculateSwap(daiIdx, hDaiIdx, amount.toString());
|
||||||
|
amountOutMin = new BigNumber(amountOutMin.toString()).multipliedBy(0.99);
|
||||||
|
|
||||||
|
const params: any = [
|
||||||
|
DAI_ADDR,
|
||||||
|
l2AmmWrapper,
|
||||||
|
wallet0.address,
|
||||||
|
1,
|
||||||
|
amount.toString(),
|
||||||
|
bonderFee.toString(),
|
||||||
|
amountOutMin.toFixed(0),
|
||||||
|
deadline,
|
||||||
|
"0",
|
||||||
|
"0"
|
||||||
|
];
|
||||||
|
|
||||||
|
const spells = [
|
||||||
|
{
|
||||||
|
connector: connectorName,
|
||||||
|
method: "bridge",
|
||||||
|
args: [params, getId]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
|
||||||
|
let receipt = await tx.wait();
|
||||||
|
latestBlock = receipt.blockNumber;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should fetch transferId from TransferSent Event", async function () {
|
||||||
|
const filter = l2BridgeInstance.connect(wallet0).filters.TransferSent();
|
||||||
|
const events = await l2BridgeInstance.connect(wallet0).queryFilter(filter, 27054896, latestBlock);
|
||||||
|
|
||||||
|
const transferSentEvent: any = events[0].args;
|
||||||
|
|
||||||
|
expect(transferSentEvent[2].toLowerCase()).to.be.equals(wallet0.address.toLowerCase());
|
||||||
|
console.log("TransferId", transferSentEvent[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should migrate from L2 to L2", async function () {
|
||||||
|
const amount = ethers.utils.parseEther("10");
|
||||||
|
|
||||||
|
const hDaiIdx = await saddleSwapInstance.connect(wallet0).getTokenIndex(hDai);
|
||||||
|
const daiIdx = await saddleSwapInstance.connect(wallet0).getTokenIndex(DAI_ADDR);
|
||||||
|
|
||||||
|
let destinationAmountOutMin = await saddleSwapInstance
|
||||||
|
.connect(wallet0)
|
||||||
|
.calculateSwap(hDaiIdx, daiIdx, amount.toString());
|
||||||
|
destinationAmountOutMin = new BigNumber(destinationAmountOutMin.toString()).multipliedBy(0.99);
|
||||||
|
|
||||||
|
let amountOutMin = await saddleSwapInstance.connect(wallet0).calculateSwap(daiIdx, hDaiIdx, amount.toString());
|
||||||
|
amountOutMin = new BigNumber(amountOutMin.toString()).multipliedBy(0.99);
|
||||||
|
|
||||||
|
const bonderFee = new BigNumber(1e9)
|
||||||
|
.multipliedBy(150000)
|
||||||
|
.multipliedBy(1.5)
|
||||||
|
.plus(new BigNumber(amount.toString()).multipliedBy(0.18));
|
||||||
|
const deadline = Date.now() + 604800;
|
||||||
|
const getId = "0";
|
||||||
|
|
||||||
|
await token.connect(wallet0).approve(l2AmmWrapper, amount.toString());
|
||||||
|
|
||||||
|
const params: any = [
|
||||||
|
DAI_ADDR,
|
||||||
|
l2AmmWrapper,
|
||||||
|
wallet0.address,
|
||||||
|
10,
|
||||||
|
amount.toString(),
|
||||||
|
bonderFee.toString(),
|
||||||
|
amountOutMin.toFixed(0),
|
||||||
|
deadline,
|
||||||
|
destinationAmountOutMin.toFixed(0),
|
||||||
|
deadline
|
||||||
|
];
|
||||||
|
|
||||||
|
const spells = [
|
||||||
|
{
|
||||||
|
connector: connectorName,
|
||||||
|
method: "bridge",
|
||||||
|
args: [params, getId]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
|
||||||
|
let receipt = await tx.wait();
|
||||||
|
latestBlock = receipt.blockNumber;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should fetch transferId from TransferSent Event", async function () {
|
||||||
|
const filter = l2BridgeInstance.connect(wallet0).filters.TransferSent();
|
||||||
|
const events = await l2BridgeInstance.connect(wallet0).queryFilter(filter, 27054896, latestBlock);
|
||||||
|
|
||||||
|
const transferSentEvent: any = events[1].args;
|
||||||
|
|
||||||
|
expect(transferSentEvent[2].toLowerCase()).to.be.equals(wallet0.address.toLowerCase());
|
||||||
|
console.log("TransferId", transferSentEvent[0]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user