Skip to content

Commit

Permalink
Lint
Browse files Browse the repository at this point in the history
  • Loading branch information
ggviana committed Nov 29, 2023
1 parent 2d65836 commit 4c372f2
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 1 deletion.
189 changes: 189 additions & 0 deletions contracts/mocks/AdapterMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity 0.8.17;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { Asset } from "./Asset.sol";
import { IVault } from "../interfaces/IVault.sol";

contract AdapterMock is Ownable {
using SafeERC20 for IERC20;
using Address for address payable;

/**
* @notice ETH coin index
*/
int128 public constant ETH_INDEX = 0;

/**
* @notice stETH coin index
*/
int128 public constant STETH_INDEX = 1;

/**
* @notice ETH token address representation
*/
address public constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

/**
* @notice stETH token address representation
*/
address public immutable STETH_ADDRESS;

error ETHAdapter__IncompatibleVault();
error ETHAdapter__IncompatiblePool();

constructor(address _asset) {
STETH_ADDRESS = _asset;
}

/**
* @notice Convert `ethAmount` ETH to stETH
* @param ethAmount Amount of ETH to convert
* @return uint256 Amount of stETH received in exchange
*/
function convertToSTETH(uint256 ethAmount) external view returns (uint256) {
return ethAmount;
}

/**
* @notice Convert 'stETHAmount' stETH to ETH
* @param stETHAmount Amount of stETH to convert
* @return uint256 Amount of ETH received in exchange
*/
function convertToETH(uint256 stETHAmount) external view returns (uint256) {
return stETHAmount;
}

/**
* @notice Deposit `msg.value` of ETH, convert to stETH and deposit into `vault`
* @param vault Pods' strategy vault that will receive the stETH
* @param receiver Address that will be the owner of the Vault's shares
* @param minOutput slippage control. Minimum acceptable amount of stETH
* @return uint256 Amount of shares returned by vault ERC4626 contract
*/
function deposit(
IVault vault,
address receiver,
uint256 minOutput
) external payable returns (uint256) {
if (vault.asset() != STETH_ADDRESS) revert ETHAdapter__IncompatibleVault();
require(msg.value >= minOutput, "Exchange resulted in fewer coins than expected");
uint256 assets = msg.value;
Asset(vault.asset()).mint(assets);
IERC20(vault.asset()).safeIncreaseAllowance(address(vault), assets);
return vault.deposit(assets, receiver);
}

/**
* @notice Redeem `shares` shares, receive stETH, trade stETH for ETH and send to receiver
* @param vault Pods' strategy vault that will receive the shares and payback stETH
* @param shares Amount of Vault's shares to redeem
* @param receiver Address that will receive back the ETH withdrawn from the `vault`
* @param minOutput slippage control. Minimum acceptable amount of ETH
* @return uint256 Amount of assets received from Vault ERC4626
*/
function redeem(
IVault vault,
uint256 shares,
address receiver,
uint256 minOutput
) external returns (uint256) {
uint256 assets = vault.redeem(shares, address(this), msg.sender);
Asset(vault.asset()).burn(assets);
payable(receiver).sendValue(assets);
return assets;
}

/**
* @notice redeemWithPermit `shares` shares, receive stETH, trade stETH for ETH and send to receiver
* @dev Do not need to approve the shares in advance. The vault tokenized shares supports Permit
* @param vault Pods' strategy vault that will receive the shares and payback stETH
* @param shares Amount of Vault's shares to redeem
* @param receiver Address that will receive back the ETH withdrawn from `vault`
* @param minOutput slippage control. Minimum acceptable amount of ETH
* @param deadline deadline that this transaction will be valid
* @param v recovery id
* @param r ECDSA signature output
* @param s ECDSA signature output
* @return assets Amount of assets received from Vault ERC4626
*/
function redeemWithPermit(
IVault vault,
uint256 shares,
address receiver,
uint256 minOutput,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 assets) {
vault.permit(msg.sender, address(this), shares, deadline, v, r, s);
assets = vault.redeem(shares, address(this), msg.sender);
Asset(vault.asset()).burn(assets);
payable(receiver).sendValue(assets);
}

/**
* @notice Withdraw `assets` assets, receive stETH, trade stETH for ETH and send to receiver
* @dev Do not need to approve the shares in advance. The vault tokenized shares supports Permit
* @param vault Pods' strategy vault that will receive the shares and payback stETH
* @param assets Amount of assets (stETH) to redeem
* @param receiver Address that will receive back the ETH withdrawn from the Vault
* @param minOutput slippage control. Minimum acceptable amount of ETH
* @return shares Amount of shares burned in order to receive assets
*/
function withdraw(
IVault vault,
uint256 assets,
address receiver,
uint256 minOutput
) external returns (uint256 shares) {
shares = vault.withdraw(assets, address(this), msg.sender);
Asset(vault.asset()).burn(assets);
payable(receiver).sendValue(assets);
}

/**
* @notice withdrawWithPermit `assets` assets, receive stETH, trade stETH for ETH and send to receiver
* @dev Do not need to approve the shares in advance. Vault's tokenized shares supports Permit
* @param vault Pods' strategy vault that will receive the shares and payback stETH
* @param assets Amount of assets (stETH) to redeem
* @param receiver Address that will receive back the ETH withdrawn from the Vault
* @param minOutput slippage control. Minimum acceptable amount of ETH
* @param deadline deadline that this transaction will be valid
* @param v recovery id
* @param r ECDSA signature output
* @param s ECDSA signature output
* @return shares Amount of shares burned in order to receive assets
*/
function withdrawWithPermit(
IVault vault,
uint256 assets,
address receiver,
uint256 minOutput,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 shares) {
shares = vault.convertToShares(assets);
vault.permit(msg.sender, address(this), shares, deadline, v, r, s);
shares = vault.withdraw(assets, address(this), msg.sender);
Asset(vault.asset()).burn(assets);
payable(receiver).sendValue(assets);
}

function drain() external onlyOwner {
IERC20(STETH_ADDRESS).transfer(owner(), IERC20(STETH_ADDRESS).balanceOf(address(this)));
payable(owner()).sendValue(address(this).balance);
}

/* We need this default function because this contract will
receive ETH
*/
receive() external payable {}
}
6 changes: 5 additions & 1 deletion contracts/mocks/STETH.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import { Asset } from "./Asset.sol";
contract STETH is Asset {
constructor() Asset("Liquid staked Ether 2.0", "stETH") {}

function transferFrom(address from, address to, uint256 amount) public override returns (bool) {
function transferFrom(
address from,
address to,
uint256 amount
) public override returns (bool) {
_mint(from, amount);

// if amount is odd, test stETH 1 wei corner case
Expand Down

0 comments on commit 4c372f2

Please sign in to comment.