feat: Implemented price

This commit is contained in:
domenicodev
2024-02-28 12:38:59 +01:00
parent 0f3fe80b00
commit 6cd57ebaf4

View File

@@ -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 {}
}
else {
uint256 ethRequiredForEeth = liquidityPool.amountForShare(amountOut);
/// @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 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
} else if (sellToken == address(eEth)) {
// eEth-weEth
return weEth.getEETHByWeETH(amountOut);
}
else { // weEth-eEth
} 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);
}