feat: Implemented price
This commit is contained in:
@@ -3,10 +3,12 @@ pragma experimental ABIEncoderV2;
|
||||
pragma solidity ^0.8.13;
|
||||
|
||||
import {IERC20, ISwapAdapter} from "src/interfaces/ISwapAdapter.sol";
|
||||
import {SafeERC20} from "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
import {SafeERC20} from
|
||||
"openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
|
||||
/// @title Etherfi Adapter
|
||||
/// @dev This contract supports the following swaps: ETH->eETH, wETH<->eETH, ETH->weETH
|
||||
/// @dev This contract supports the following swaps: ETH->eETH, wETH<->eETH,
|
||||
/// ETH->weETH
|
||||
contract EtherfiAdapter is ISwapAdapter {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
@@ -22,13 +24,16 @@ contract EtherfiAdapter is ISwapAdapter {
|
||||
|
||||
/// @dev Check if tokens in input are supported by this adapter
|
||||
modifier checkInputTokens(address sellToken, address buyToken) {
|
||||
if(sellToken == buyToken) {
|
||||
if (sellToken == buyToken) {
|
||||
revert Unavailable("This pool only supports eETH, weEth and ETH");
|
||||
}
|
||||
if(sellToken != address(weEth) && sellToken != address(eEth) && sellToken != address(0)) {
|
||||
if (
|
||||
sellToken != address(weEth) && sellToken != address(eEth)
|
||||
&& sellToken != address(0)
|
||||
) {
|
||||
revert Unavailable("This pool only supports eETH, weEth and ETH");
|
||||
}
|
||||
if(buyToken != address(weEth) && buyToken != address(eEth)) {
|
||||
if (buyToken != address(weEth) && buyToken != address(eEth)) {
|
||||
revert Unavailable("This pool only supports eETH, weEth and ETH");
|
||||
}
|
||||
_;
|
||||
@@ -37,23 +42,66 @@ contract EtherfiAdapter is ISwapAdapter {
|
||||
/// @dev enable receive as this contract supports ETH
|
||||
receive() external payable {}
|
||||
|
||||
/// @inheritdoc ISwapAdapter
|
||||
function price(
|
||||
bytes32 _poolId,
|
||||
bytes32,
|
||||
IERC20 _sellToken,
|
||||
IERC20 _buyToken,
|
||||
uint256[] memory _specifiedAmounts
|
||||
) external view override returns (Fraction[] memory _prices) {
|
||||
revert NotImplemented("TemplateSwapAdapter.price");
|
||||
)
|
||||
external
|
||||
view
|
||||
override
|
||||
checkInputTokens(address(_sellToken), address(_buyToken))
|
||||
returns (Fraction[] memory _prices)
|
||||
{
|
||||
_prices = new Fraction[](_specifiedAmounts.length);
|
||||
address sellTokenAddress = address(_sellToken);
|
||||
address buyTokenAddress = address(_buyToken);
|
||||
|
||||
for (uint256 i = 0; i < _specifiedAmounts.length; i++) {
|
||||
_prices[i] = getPriceAt(sellTokenAddress, buyTokenAddress, _specifiedAmounts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function swap(
|
||||
bytes32 poolId,
|
||||
bytes32,
|
||||
IERC20 sellToken,
|
||||
IERC20 buyToken,
|
||||
OrderSide side,
|
||||
uint256 specifiedAmount
|
||||
) external returns (Trade memory trade) {
|
||||
revert NotImplemented("TemplateSwapAdapter.swap");
|
||||
)
|
||||
external
|
||||
override
|
||||
checkInputTokens(address(sellToken), address(buyToken))
|
||||
returns (Trade memory trade)
|
||||
{
|
||||
// if (specifiedAmount == 0) {
|
||||
// return trade;
|
||||
// }
|
||||
|
||||
// address sellTokenAddress = address(sellToken);
|
||||
// address buyTokenAddress = address(buyToken);
|
||||
// uint256 gasBefore = gasleft();
|
||||
// if (sellTokenAddress == address(0)) {
|
||||
// if (buyTokenAddress == address(eEth)) {
|
||||
// trade.calculatedAmount = swapEthForEeth(specifiedAmount,
|
||||
// side);
|
||||
// } else {
|
||||
// trade.calculatedAmount = swapEthForWeEth(specifiedAmount,
|
||||
// side);
|
||||
// }
|
||||
// } else {
|
||||
// if (sellTokenAddress == address(eEth)) {
|
||||
// trade.calculatedAmount = swapEthForWeEth(specifiedAmount,
|
||||
// side);
|
||||
// } else {
|
||||
// trade.calculatedAmount = swapWeEthForEeth(specifiedAmount,
|
||||
// side);
|
||||
// }
|
||||
// }
|
||||
// trade.gasUsed = gasBefore - gasleft();
|
||||
// // trade.price = getPriceAt();
|
||||
}
|
||||
|
||||
function getLimits(bytes32, IERC20 sellToken, IERC20 buyToken)
|
||||
@@ -67,31 +115,16 @@ contract EtherfiAdapter is ISwapAdapter {
|
||||
address buyTokenAddress = address(buyToken);
|
||||
limits = new uint256[](2);
|
||||
|
||||
if(sellTokenAddress == address(0)) {
|
||||
if(buyTokenAddress == address(eEth)) {
|
||||
|
||||
if (sellTokenAddress == address(0)) {
|
||||
if (buyTokenAddress == address(eEth)) {} else { // ETH-weEth
|
||||
}
|
||||
else { // ETH-weEth
|
||||
|
||||
} else if (sellTokenAddress == address(weEth)) {
|
||||
if (buyTokenAddress == address(0)) {} else { // weEth-ETH
|
||||
}
|
||||
} else if (sellTokenAddress == address(eEth)) {
|
||||
if (buyTokenAddress == address(0)) {} else { // eEth-weEth
|
||||
}
|
||||
}
|
||||
else if(sellTokenAddress == address(weEth)) {
|
||||
if(buyTokenAddress == address(0)) {
|
||||
|
||||
}
|
||||
else { // weEth-ETH
|
||||
|
||||
}
|
||||
}
|
||||
else if(sellTokenAddress == address(eEth)) {
|
||||
if(buyTokenAddress == address(0)) {
|
||||
|
||||
}
|
||||
else { // eEth-weEth
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getCapabilities(bytes32 poolId, IERC20 sellToken, IERC20 buyToken)
|
||||
@@ -125,112 +158,184 @@ contract EtherfiAdapter is ISwapAdapter {
|
||||
|
||||
/// @notice Swap ETH for eETH
|
||||
/// @param amount amountIn or amountOut depending on side
|
||||
function swapEthForEeth(uint256 amount, OrderSide side) internal returns (uint256) {
|
||||
if(side == OrderSide.Buy) {
|
||||
function swapEthForEeth(uint256 amount, OrderSide side)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
if (side == OrderSide.Buy) {
|
||||
uint256 amountIn = getAmountIn(address(0), address(eEth), amount);
|
||||
uint256 receivedAmount = liquidityPool.deposit{value: amountIn}();
|
||||
IERC20(address(eEth)).safeTransfer(address(msg.sender), receivedAmount);
|
||||
IERC20(address(eEth)).safeTransfer(
|
||||
address(msg.sender), receivedAmount
|
||||
);
|
||||
return amountIn;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
uint256 receivedAmount = liquidityPool.deposit{value: amount}();
|
||||
IERC20(address(eEth)).safeTransfer(address(msg.sender), receivedAmount);
|
||||
IERC20(address(eEth)).safeTransfer(
|
||||
address(msg.sender), receivedAmount
|
||||
);
|
||||
return receivedAmount;
|
||||
}
|
||||
}
|
||||
|
||||
/// @notice Swap ETH for weEth
|
||||
/// @param amount amountIn or amountOut depending on side
|
||||
function swapEthForWeEth(uint256 amount, OrderSide side) internal returns (uint256) {
|
||||
if(side == OrderSide.Buy) {
|
||||
function swapEthForWeEth(uint256 amount, OrderSide side)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
if (side == OrderSide.Buy) {
|
||||
uint256 amountIn = getAmountIn(address(0), address(weEth), amount);
|
||||
IERC20(address(eEth)).approve(address(weEth), amountIn);
|
||||
uint256 receivedAmountEeth = liquidityPool.deposit{value: amountIn}();
|
||||
uint256 receivedAmountEeth =
|
||||
liquidityPool.deposit{value: amountIn}();
|
||||
uint256 receivedAmount = weEth.wrap(receivedAmountEeth);
|
||||
IERC20(address(weEth)).safeTransfer(address(msg.sender), receivedAmount);
|
||||
IERC20(address(weEth)).safeTransfer(
|
||||
address(msg.sender), receivedAmount
|
||||
);
|
||||
return amountIn;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
IERC20(address(eEth)).approve(address(weEth), amount);
|
||||
uint256 receivedAmountEeth = liquidityPool.deposit{value: amount}();
|
||||
uint256 receivedAmount = weEth.wrap(receivedAmountEeth);
|
||||
IERC20(address(weEth)).safeTransfer(address(msg.sender), receivedAmount);
|
||||
IERC20(address(weEth)).safeTransfer(
|
||||
address(msg.sender), receivedAmount
|
||||
);
|
||||
return receivedAmount;
|
||||
}
|
||||
}
|
||||
|
||||
/// @notice Get amountIn for swap functions with OrderSide buy
|
||||
function getAmountIn(address sellToken, address buyToken, uint256 amountOut) internal view returns (uint256) {
|
||||
if(sellToken == address(0)) {
|
||||
if(buyToken == address(eEth)) {
|
||||
return liquidityPool.amountForShare(amountOut);
|
||||
/// @notice Swap eETH for weETH
|
||||
/// @param amount amountIn or amountOut depending on side
|
||||
function swapEethForWeEth(uint256 amount, OrderSide side)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
if (side == OrderSide.Buy) {} else {}
|
||||
}
|
||||
|
||||
/// @notice Swap weETH for eEth
|
||||
/// @param amount amountIn or amountOut depending on side
|
||||
function swapWeEthForEeth(uint256 amount, OrderSide side)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
if (side == OrderSide.Buy) {} else {}
|
||||
}
|
||||
|
||||
/// @notice Get swap price
|
||||
/// @param sellToken token to sell
|
||||
/// @param buyToken token to buy
|
||||
function getPriceAt(address sellToken, address buyToken, uint256 amount)
|
||||
internal
|
||||
view
|
||||
returns (Fraction memory)
|
||||
{
|
||||
if (sellToken == address(0)) {
|
||||
if (buyToken == address(eEth)) {
|
||||
return Fraction(liquidityPool.sharesForAmount(amount), amount);
|
||||
} else {
|
||||
uint256 eEthOut = liquidityPool.sharesForAmount(amount);
|
||||
return Fraction(liquidityPool.sharesForAmount(eEthOut), amount);
|
||||
}
|
||||
else {
|
||||
uint256 ethRequiredForEeth = liquidityPool.amountForShare(amountOut);
|
||||
return liquidityPool.amountForShare(ethRequiredForEeth);
|
||||
}
|
||||
}
|
||||
else if(sellToken == address(eEth)) { // eEth-weEth
|
||||
return weEth.getEETHByWeETH(amountOut);
|
||||
}
|
||||
else { // weEth-eEth
|
||||
return weEth.getWeETHByeETH(amountOut);
|
||||
} else if (sellToken == address(eEth)) {
|
||||
return Fraction(liquidityPool.sharesForAmount(amount), amount);
|
||||
} else {
|
||||
return Fraction(liquidityPool.amountForShare(amount), amount);
|
||||
}
|
||||
}
|
||||
|
||||
/// @notice Get amountIn for swap functions with OrderSide buy
|
||||
function getAmountIn(address sellToken, address buyToken, uint256 amountOut)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
if (sellToken == address(0)) {
|
||||
if (buyToken == address(eEth)) {
|
||||
return liquidityPool.amountForShare(amountOut);
|
||||
} else {
|
||||
uint256 ethRequiredForEeth =
|
||||
liquidityPool.amountForShare(amountOut);
|
||||
return liquidityPool.amountForShare(ethRequiredForEeth);
|
||||
}
|
||||
} else if (sellToken == address(eEth)) {
|
||||
// eEth-weEth
|
||||
return weEth.getEETHByWeETH(amountOut);
|
||||
} else {
|
||||
// weEth-eEth
|
||||
return weEth.getWeETHByeETH(amountOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IWithdrawRequestNFT {
|
||||
function requestWithdraw(
|
||||
uint96 amountOfEEth,
|
||||
uint96 shareOfEEth,
|
||||
address recipient,
|
||||
uint256 fee
|
||||
) external payable returns (uint256);
|
||||
|
||||
function requestWithdraw(uint96 amountOfEEth, uint96 shareOfEEth, address recipient, uint256 fee)
|
||||
external payable returns (uint256);
|
||||
|
||||
function getClaimableAmount(uint256 tokenId) external view returns (uint256);
|
||||
function getClaimableAmount(uint256 tokenId)
|
||||
external
|
||||
view
|
||||
returns (uint256);
|
||||
|
||||
function claimWithdraw(uint256 tokenId) external;
|
||||
|
||||
}
|
||||
|
||||
interface ILiquidityPool {
|
||||
|
||||
function numPendingDeposits() external view returns (uint32);
|
||||
function totalValueOutOfLp() external view returns (uint128);
|
||||
function totalValueInLp() external view returns (uint128);
|
||||
function getTotalEtherClaimOf(address _user) external view returns (uint256);
|
||||
function getTotalEtherClaimOf(address _user)
|
||||
external
|
||||
view
|
||||
returns (uint256);
|
||||
function getTotalPooledEther() external view returns (uint256);
|
||||
function sharesForAmount(uint256 _amount) external view returns (uint256);
|
||||
function sharesForWithdrawalAmount(uint256 _amount) external view returns (uint256);
|
||||
function sharesForWithdrawalAmount(uint256 _amount)
|
||||
external
|
||||
view
|
||||
returns (uint256);
|
||||
function amountForShare(uint256 _share) external view returns (uint256);
|
||||
|
||||
function deposit() external payable returns (uint256);
|
||||
function deposit(address _referral) external payable returns (uint256);
|
||||
function deposit(address _user, address _referral) external payable returns (uint256);
|
||||
function deposit(address _user, address _referral)
|
||||
external
|
||||
payable
|
||||
returns (uint256);
|
||||
|
||||
function requestWithdraw(address recipient, uint256 amount) external returns (uint256);
|
||||
function requestWithdraw(address recipient, uint256 amount)
|
||||
external
|
||||
returns (uint256);
|
||||
function withdrawRequestNFT() external view returns (IWithdrawRequestNFT);
|
||||
|
||||
}
|
||||
|
||||
interface IeEth {
|
||||
|
||||
function liquidityPool() external view returns (ILiquidityPool);
|
||||
|
||||
function totalShares() external view returns (uint256);
|
||||
|
||||
function shares(address _user) external view returns (uint256);
|
||||
|
||||
}
|
||||
|
||||
interface IWeEth {
|
||||
|
||||
function eETH() external view returns (IeEth);
|
||||
|
||||
function getWeETHByeETH(uint256 _eETHAmount) external view returns (uint256);
|
||||
function getWeETHByeETH(uint256 _eETHAmount)
|
||||
external
|
||||
view
|
||||
returns (uint256);
|
||||
|
||||
function getEETHByWeETH(uint256 _weETHAmount) external view returns (uint256);
|
||||
function getEETHByWeETH(uint256 _weETHAmount)
|
||||
external
|
||||
view
|
||||
returns (uint256);
|
||||
|
||||
function wrap(uint256 _eETHAmount) external returns (uint256);
|
||||
|
||||
function unwrap(uint256 _weETHAmount) external returns (uint256);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user