Skip to content

Commit ab36769

Browse files
authored
router (#260)
1 parent 319e91e commit ab36769

File tree

2 files changed

+109
-5
lines changed

2 files changed

+109
-5
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// SPDX-License-Identifier: GPL-3.0-only
2+
pragma solidity 0.7.6;
3+
pragma abicoder v2;
4+
5+
import {GeyserRouter, TransferHelper, IERC20, IERC721, IGeyser} from "./GeyserRouter.sol";
6+
7+
/// @notice Interface for a Charm LP token
8+
interface ICharmLiqToken is IERC20 {
9+
function token0() external view returns (address);
10+
11+
function token1() external view returns (address);
12+
13+
function deposit(
14+
uint256,
15+
uint256,
16+
uint256,
17+
uint256,
18+
address
19+
)
20+
external
21+
returns (
22+
uint256,
23+
uint256,
24+
uint256
25+
);
26+
}
27+
28+
/// @title CharmGeyserRouter
29+
/// @notice Convenience contract to stake Charm LP tokens on geysers
30+
/// @dev Security contact: dev-support@ampleforth.org
31+
contract CharmGeyserRouter is GeyserRouter {
32+
using TransferHelper for address;
33+
34+
struct LiqCreationPayload {
35+
uint256 token0Amt;
36+
uint256 token1Amt;
37+
uint256 token0MinAmt;
38+
uint256 token1MinAmt;
39+
}
40+
41+
function createLiqAndStake(
42+
address geyser,
43+
address vault,
44+
bytes calldata permission,
45+
LiqCreationPayload memory d
46+
) public {
47+
// Expects the geyser's staking token to be a Charm liquidity token
48+
ICharmLiqToken charm = ICharmLiqToken(IGeyser(geyser).getGeyserData().stakingToken);
49+
address depositToken0 = charm.token0();
50+
address depositToken1 = charm.token1();
51+
52+
// Get deposit tokens from user
53+
depositToken0.safeTransferFrom(msg.sender, address(this), d.token0Amt);
54+
depositToken1.safeTransferFrom(msg.sender, address(this), d.token1Amt);
55+
56+
// Creates a charm liquidity position and
57+
// transfers liquidity tokens directly to the vault
58+
_checkAndApproveMax(depositToken0, address(charm), d.token0Amt);
59+
_checkAndApproveMax(depositToken1, address(charm), d.token1Amt);
60+
(uint256 lpAmt,,) = charm.deposit(d.token0Amt, d.token1Amt, d.token0MinAmt, d.token1MinAmt, vault);
61+
62+
// Stake liquidity tokens from the vault
63+
IGeyser(geyser).stake(vault, lpAmt, permission);
64+
65+
// Transfer any remaining dust deposit tokens
66+
_transferAll(depositToken0, msg.sender);
67+
_transferAll(depositToken1, msg.sender);
68+
}
69+
70+
function create2VaultCreateLiqAndStake(
71+
address geyser,
72+
address vaultFactory,
73+
address vaultOwner,
74+
bytes32 salt,
75+
bytes calldata permission,
76+
LiqCreationPayload memory d
77+
) external returns (address vault) {
78+
// create vault
79+
vault = create2Vault(vaultFactory, salt);
80+
81+
// transfer ownership
82+
IERC721(vaultFactory).safeTransferFrom(address(this), vaultOwner, uint256(vault));
83+
84+
// create liquidity and stake
85+
createLiqAndStake(geyser, vault, permission, d);
86+
}
87+
88+
/// @dev Checks if the spender has sufficient allowance. If not, approves the maximum possible amount.
89+
function _checkAndApproveMax(
90+
address token,
91+
address spender,
92+
uint256 amount
93+
) private {
94+
uint256 allowance = IERC20(token).allowance(address(this), spender);
95+
if (allowance < amount) {
96+
IERC20(token).approve(spender, type(uint256).max);
97+
}
98+
}
99+
100+
/// @dev Transfers the entire token balance to the given address.
101+
function _transferAll(address token, address to) private {
102+
token.safeTransfer(to, IERC20(token).balanceOf(address(this)));
103+
}
104+
}

contracts/RouterV1.sol renamed to contracts/Router/GeyserRouter.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Recei
88
import {IERC20Permit} from "@openzeppelin/contracts/drafts/IERC20Permit.sol";
99
import {TransferHelper} from "@uniswap/lib/contracts/libraries/TransferHelper.sol";
1010

11-
import {IGeyser} from "./Geyser.sol";
12-
import {IUniversalVault} from "./UniversalVault.sol";
13-
import {IFactory} from "./Factory/IFactory.sol";
11+
import {IGeyser} from "../Geyser.sol";
12+
import {IUniversalVault} from "../UniversalVault.sol";
13+
import {IFactory} from "../Factory/IFactory.sol";
1414

15-
/// @title RouterV1
15+
/// @title GeyserRouter
1616
/// @notice Convenience contract for ampleforth geyser
1717
/// @dev Security contact: dev-support@ampleforth.org
18-
contract RouterV1 is IERC721Receiver {
18+
contract GeyserRouter is IERC721Receiver {
1919
function onERC721Received(
2020
address,
2121
address,

0 commit comments

Comments
 (0)