This repository has been archived by the owner on Mar 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
LMPVaultRouter.sol
96 lines (82 loc) · 3.77 KB
/
LMPVaultRouter.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// forked from https://github.com/fei-protocol/ERC4626/blob/main/src/ERC4626Router.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity 0.8.17;
import { IERC20, SafeERC20 } from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol";
import { Address } from "openzeppelin-contracts/utils/Address.sol";
import { Errors } from "src/utils/Errors.sol";
import { ISystemRegistry } from "src/interfaces/ISystemRegistry.sol";
import { ILMPVault, ILMPVaultRouter } from "src/interfaces/vault/ILMPVaultRouter.sol";
import { SwapParams } from "src/interfaces/liquidation/IAsyncSwapper.sol";
import { LMPVaultRouterBase } from "src/vault/LMPVaultRouterBase.sol";
/// @title ERC4626Router contract
contract LMPVaultRouter is ILMPVaultRouter, LMPVaultRouterBase {
using SafeERC20 for IERC20;
using Address for address;
ISystemRegistry private immutable systemRegistry;
constructor(ISystemRegistry _systemRegistry, address _weth9) LMPVaultRouterBase(_weth9) {
systemRegistry = _systemRegistry;
}
// For the below, no approval needed, assumes vault is already max approved
/// @inheritdoc ILMPVaultRouter
function withdrawToDeposit(
ILMPVault fromVault,
ILMPVault toVault,
address to,
uint256 amount,
uint256 maxSharesIn,
uint256 minSharesOut
) external override returns (uint256 sharesOut) {
withdraw(fromVault, address(this), amount, maxSharesIn, false);
return _deposit(toVault, to, amount, minSharesOut);
}
/// @inheritdoc ILMPVaultRouter
function swapAndDepositToVault(
address swapper,
SwapParams memory swapParams,
ILMPVault vault,
address to,
uint256 minSharesOut
) external returns (uint256 sharesOut) {
systemRegistry.asyncSwapperRegistry().verifyIsRegistered(swapper);
pullToken(IERC20(swapParams.sellTokenAddress), swapParams.sellAmount, address(this));
// verify that the swap is for the vault asset
if (swapParams.buyTokenAddress != vault.asset()) revert Errors.InvalidParams();
bytes memory data = swapper.functionDelegateCall(
abi.encodeWithSignature("swap((address,uint256,address,uint256,bytes,bytes))", swapParams), "SwapFailed"
);
uint256 amountReceived = abi.decode(data, (uint256));
return _deposit(vault, to, amountReceived, minSharesOut);
}
/// @inheritdoc ILMPVaultRouter
function redeemToDeposit(
ILMPVault fromVault,
ILMPVault toVault,
address to,
uint256 shares,
uint256 minSharesOut
) external override returns (uint256 sharesOut) {
// amount out passes through so only one slippage check is needed
uint256 amount = redeem(fromVault, address(this), shares, 0, false);
return _deposit(toVault, to, amount, minSharesOut);
}
/// @inheritdoc ILMPVaultRouter
function depositMax(
ILMPVault vault,
address to,
uint256 minSharesOut
) public override returns (uint256 sharesOut) {
IERC20 asset = IERC20(vault.asset());
uint256 assetBalance = asset.balanceOf(msg.sender);
uint256 maxDeposit = vault.maxDeposit(to);
uint256 amount = maxDeposit < assetBalance ? maxDeposit : assetBalance;
pullToken(asset, amount, address(this));
return _deposit(vault, to, amount, minSharesOut);
}
/// @inheritdoc ILMPVaultRouter
function redeemMax(ILMPVault vault, address to, uint256 minAmountOut) public override returns (uint256 amountOut) {
uint256 shareBalance = vault.balanceOf(msg.sender);
uint256 maxRedeem = vault.maxRedeem(msg.sender);
uint256 amountShares = maxRedeem < shareBalance ? maxRedeem : shareBalance;
return redeem(vault, to, amountShares, minAmountOut, false);
}
}