// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)pragmasolidity ^0.8.0;/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/interfaceIERC20{
/**
* @dev Returns the amount of tokens in existence.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/functionbalanceOf(address account) externalviewreturns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransfer(address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/functionallowance(address owner, address spender) externalviewreturns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/functionapprove(address spender, uint256 amount) externalreturns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransferFrom(address sender,
address recipient,
uint256 amount
) externalreturns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/eventTransfer(addressindexedfrom, addressindexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/eventApproval(addressindexed owner, addressindexed spender, uint256 value);
}
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;import { IERC20 } from"@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IVault } from"../interfaces/IVault.sol";
import { IWETH9 } from"../interfaces/IWETH9.sol";
import { ISfrxETH } from"../interfaces/ISfrxETH.sol";
contractOETHZapper{
IERC20 publicimmutable oeth;
IVault publicimmutable vault;
IWETH9 publicconstant weth =
IWETH9(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
IERC20 publicconstant frxeth =
IERC20(0x5E8422345238F34275888049021821E8E08CAa1f);
ISfrxETH publicconstant sfrxeth =
ISfrxETH(0xac3E018457B222d93114458476f3E3416Abbe38F);
addressprivateconstant ETH_MARKER =0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
eventZap(addressindexed minter, addressindexed asset, uint256 amount);
constructor(address _oeth, address _vault) {
oeth = IERC20(_oeth);
vault = IVault(_vault);
weth.approve(address(_vault), type(uint256).max);
frxeth.approve(address(_vault), type(uint256).max);
}
/**
* @dev Deposit ETH and receive OETH in return.
* Will verify that the user is sent 1:1 for ETH.
*/receive() externalpayable{
deposit();
}
/**
* @dev Deposit ETH and receive OETH in return
* Will verify that the user is sent 1:1 for ETH.
* @return Amount of OETH sent to user
*/functiondeposit() publicpayablereturns (uint256) {
uint256 balance =address(this).balance;
weth.deposit{ value: balance }();
emit Zap(msg.sender, ETH_MARKER, balance);
return _mint(address(weth), balance);
}
/**
* @dev Deposit SFRXETH to the vault and receive OETH in return
* @param amount Amount of SFRXETH to deposit
* @param minOETH Minimum amount of OETH to receive
* @return Amount of OETH sent to user
*/functiondepositSFRXETH(uint256 amount, uint256 minOETH)
externalreturns (uint256)
{
sfrxeth.redeem(amount, address(this), msg.sender);
emit Zap(msg.sender, address(sfrxeth), amount);
return _mint(address(frxeth), minOETH);
}
/**
* @dev Internal function to mint OETH from an asset
* @param asset Address of asset for the vault to mint from
* @param minOETH Minimum amount of OETH to for user to receive
* @return Amount of OETH sent to user
*/function_mint(address asset, uint256 minOETH) internalreturns (uint256) {
uint256 toMint = IERC20(asset).balanceOf(address(this));
vault.mint(asset, toMint, minOETH);
uint256 mintedAmount = oeth.balanceOf(address(this));
require(mintedAmount >= minOETH, "Zapper: not enough minted");
require(oeth.transfer(msg.sender, mintedAmount));
return mintedAmount;
}
}