Blockwell

yVault_ZapInOut_General_V1_5

About

Stats

Public Functions 14
Event Types 3
Code Size 48,144 bytes

Library Use

Uses SafeMath for uint256.
Uses Address for address.
Uses SafeERC20 for IERC20.

Events (3) keyboard_arrow_up

OwnershipTransferred Event

Parameters help
previousOwner
address help
newOwner
address help

Zapin Event

Parameters help
_toWhomToIssue
address help
_toYVaultAddress
address help
_Outgoing
uint256 help

Zapout Event

Parameters help
_toWhomToIssue
address help
_fromYVaultAddress
address help
_toTokenAddress
address help
_tokensRecieved
uint256 help

UniSwapV2FactoryAddress Constant

IUniswapV2Factory help

uniswapRouter Constant

IUniswapRouter02 help

lendingPoolAddressProvider Constant

IAaveLendingPoolAddressesProvider help

yCurveExchangeAddress Constant

address help

sBtcCurveExchangeAddress Constant

address help

bUSDCurveExchangeAddress Constant

address help

threeCurveExchangeAddress Constant

address help

cUSDCurveExchangeAddress Constant

address help

yCurvePoolTokenAddress Constant

address help

sBtcCurvePoolTokenAddress Constant

address help

bUSDCurvePoolTokenAddress Constant

address help

threeCurvePoolTokenAddress Constant

address help

cUSDCurvePoolTokenAddress Constant

address help

ETHAddress Constant

address help

wethTokenAddress Constant

address help

zgoodwillAddress Constant

address help

deadline Constant

uint256 help
0xf000000000000000000000000000000000000000000000000000000000000000

stopped Variable

bool help

goodwill Variable

uint16 help

CurveZapInGeneral Variable

address help

CurveZapOutGeneral Variable

address help

_owner Variable

address help

token2Exchange Variable

mapping(address => address) help

_notEntered Variable

bool help
Internal Variable

Functions Expand All Collapse All

owner keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help view
Source Code
function owner() public view returns (address) {
  return _owner;
}

isOwner keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help view
Source Code
function isOwner() public view returns (bool) {
  return _msgSender() == _owner;
}

renounceOwnership keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlyOwner checks for the following:
null
Source Code
function renounceOwnership() public onlyOwner {
  emit OwnershipTransferred(_owner, address(0));
  _owner = address(0);
}

transferOwnership keyboard_arrow_up

Parameters help

Name Type
newOwner
address help

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlyOwner checks for the following:
null

Requirements help

Source Code
function transferOwnership(address payable newOwner) public onlyOwner {
  _transferOwnership(newOwner);
}

updateCurveZapIn keyboard_arrow_up

Parameters help

Name Type
CurveZapInGeneralAddress
address help

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlyOwner checks for the following:
null

Requirements help

Source Code
function updateCurveZapIn(address CurveZapInGeneralAddress) public onlyOwner {
  require(CurveZapInGeneralAddress != address(0), "Invalid Address");
  CurveZapInGeneral = ICurveZapInGeneral(CurveZapInGeneralAddress);
}

updateCurveZapOut keyboard_arrow_up

Parameters help

Name Type
CurveZapOutGeneralAddress
address help

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlyOwner checks for the following:
null

Requirements help

Source Code
function updateCurveZapOut(address CurveZapOutGeneralAddress) public onlyOwner {
  require(CurveZapOutGeneralAddress != address(0), "Invalid Address");
  CurveZapOutGeneral = ICurveZapOutGeneral(CurveZapOutGeneralAddress);
}

addNewCurveExchange keyboard_arrow_up

Parameters help

Name Type
curvePoolToken
address help
curveExchangeAddress
address help

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlyOwner checks for the following:
null

Requirements help

Source Code
function addNewCurveExchange(
  address curvePoolToken,
  address curveExchangeAddress
) public onlyOwner {
  require(
    curvePoolToken != address(0) && curveExchangeAddress != address(0),
    "Invalid Address"
  );
  token2Exchange[curvePoolToken] = curveExchangeAddress;
}

ZapIn keyboard_arrow_up

Parameters help

Name Type
_toWhomToIssue
address help
_toYVaultAddress
address help
_vaultType
uint16 help
_fromTokenAddress
address help
_amount
uint256 help
_minYTokens
uint256 help

Properties

Visibility help public
Mutability help payable

Modifiers help

Source Code
function ZapIn(
  address _toWhomToIssue,
  address _toYVaultAddress,
  uint16 _vaultType,
  address _fromTokenAddress,
  uint256 _amount,
  uint256 _minYTokens
) public payable nonReentrant stopInEmergency returns (uint256) {
  yVault vaultToEnter = yVault(_toYVaultAddress);
  address underlyingVaultToken = vaultToEnter.token();

  if (_fromTokenAddress == address(0)) {
    require(msg.value > 0, "ERR: No ETH sent");
  } else {
    require(_amount > 0, "Err: No Tokens Sent");
    require(msg.value == 0, "ERR: ETH sent with Token");

    IERC20(_fromTokenAddress).safeTransferFrom(
      msg.sender,
      address(this),
      _amount
    );
  }

  uint256 iniYTokensBal = IERC20(address(vaultToEnter)).balanceOf(
    address(this)
  );

  if (underlyingVaultToken == _fromTokenAddress) {
    IERC20(underlyingVaultToken).safeApprove(address(vaultToEnter), _amount);
    vaultToEnter.deposit(_amount);
  } else {
    // Curve Vaults
    if (_vaultType == 2) {
      address curveExchangeAddr = token2Exchange[underlyingVaultToken];

      uint256 tokensBought;
      if (_fromTokenAddress == address(0)) {
        tokensBought = CurveZapInGeneral.ZapIn.value(msg.value)(
          address(this),
          address(0),
          curveExchangeAddr,
          msg.value,
          0
        );
      } else {
        IERC20(_fromTokenAddress).safeApprove(
          address(CurveZapInGeneral),
          _amount
        );
        tokensBought = CurveZapInGeneral.ZapIn(
          address(this),
          _fromTokenAddress,
          curveExchangeAddr,
          _amount,
          0
        );
      }

      IERC20(underlyingVaultToken).safeApprove(
        address(vaultToEnter),
        tokensBought
      );
      vaultToEnter.deposit(tokensBought);
    } else if (_vaultType == 1) {
      address underlyingAsset = IAToken(underlyingVaultToken)
      .underlyingAssetAddress();

      uint256 tokensBought;
      if (_fromTokenAddress == address(0)) {
        tokensBought = _eth2Token(underlyingAsset);
      } else {
        tokensBought = _token2Token(
          _fromTokenAddress,
          underlyingAsset,
          _amount
        );
      }

      IERC20(underlyingAsset).safeApprove(
        lendingPoolAddressProvider.getLendingPoolCore(),
        tokensBought
      );

      IAaveLendingPool(lendingPoolAddressProvider.getLendingPool()).deposit(
        underlyingAsset,
        tokensBought,
        0
      );

      uint256 aTokensBought = IERC20(underlyingVaultToken).balanceOf(
        address(this)
      );
      IERC20(underlyingVaultToken).safeApprove(
        address(vaultToEnter),
        aTokensBought
      );
      vaultToEnter.deposit(aTokensBought);
    } else {
      uint256 tokensBought;
      if (_fromTokenAddress == address(0)) {
        tokensBought = _eth2Token(underlyingVaultToken);
      } else {
        tokensBought = _token2Token(
          _fromTokenAddress,
          underlyingVaultToken,
          _amount
        );
      }

      IERC20(underlyingVaultToken).safeApprove(
        address(vaultToEnter),
        tokensBought
      );
      vaultToEnter.deposit(tokensBought);
    }
  }

  uint256 yTokensRec = IERC20(address(vaultToEnter))
  .balanceOf(address(this))
  .sub(iniYTokensBal);
  require(yTokensRec >= _minYTokens, "High Slippage");

  //transfer goodwill
  uint256 goodwillPortion = _transferGoodwill(
    address(vaultToEnter),
    yTokensRec
  );

  IERC20(address(vaultToEnter)).safeTransfer(
    _toWhomToIssue,
    yTokensRec.sub(goodwillPortion)
  );

  emit Zapin(
    _toWhomToIssue,
    address(vaultToEnter),
    yTokensRec.sub(goodwillPortion)
  );

  return (yTokensRec.sub(goodwillPortion));
}

ZapOut keyboard_arrow_up

Parameters help

Name Type
_toWhomToIssue
address help
_ToTokenContractAddress
address help
_fromYVaultAddress
address help
_vaultType
uint16 help
_IncomingAmt
uint256 help
_minTokensRec
uint256 help

Properties

Visibility help public
Mutability help transaction

Modifiers help

Source Code
function ZapOut(
  address payable _toWhomToIssue,
  address _ToTokenContractAddress,
  address _fromYVaultAddress,
  uint16 _vaultType,
  uint256 _IncomingAmt,
  uint256 _minTokensRec
) public nonReentrant stopInEmergency returns (uint256) {
  yVault vaultToExit = yVault(_fromYVaultAddress);
  address underlyingVaultToken = vaultToExit.token();

  IERC20(address(vaultToExit)).safeTransferFrom(
    msg.sender,
    address(this),
    _IncomingAmt
  );

  uint256 goodwillPortion = _transferGoodwill(
    address(vaultToExit),
    _IncomingAmt
  );

  vaultToExit.withdraw(_IncomingAmt.sub(goodwillPortion));
  uint256 underlyingReceived = IERC20(underlyingVaultToken).balanceOf(
    address(this)
  );

  uint256 toTokensReceived;
  if (_ToTokenContractAddress == underlyingVaultToken) {
    IERC20(underlyingVaultToken).safeTransfer(
      _toWhomToIssue,
      underlyingReceived
    );
    toTokensReceived = underlyingReceived;
  } else {
    if (_vaultType == 2) {
      toTokensReceived = _withdrawFromCurve(
        underlyingVaultToken,
        underlyingReceived,
        _toWhomToIssue,
        _ToTokenContractAddress,
        0
      );
    } else if (_vaultType == 1) {
      // unwrap atoken
      IAToken(underlyingVaultToken).redeem(underlyingReceived);
      address underlyingAsset = IAToken(underlyingVaultToken)
      .underlyingAssetAddress();

      // swap
      if (_ToTokenContractAddress == address(0)) {
        toTokensReceived = _token2Eth(
          underlyingAsset,
          underlyingReceived,
          _toWhomToIssue
        );
      } else {
        toTokensReceived = _token2Token(
          underlyingAsset,
          _ToTokenContractAddress,
          underlyingReceived
        );
        IERC20(_ToTokenContractAddress).safeTransfer(
          _toWhomToIssue,
          toTokensReceived
        );
      }
    } else {
      if (_ToTokenContractAddress == address(0)) {
        toTokensReceived = _token2Eth(
          underlyingVaultToken,
          underlyingReceived,
          _toWhomToIssue
        );
      } else {
        toTokensReceived = _token2Token(
          underlyingVaultToken,
          _ToTokenContractAddress,
          underlyingReceived
        );

        IERC20(_ToTokenContractAddress).safeTransfer(
          _toWhomToIssue,
          toTokensReceived
        );
      }
    }
  }

  require(toTokensReceived >= _minTokensRec, "High Slippage");

  emit Zapout(
    _toWhomToIssue,
    _fromYVaultAddress,
    _ToTokenContractAddress,
    toTokensReceived
  );

  return toTokensReceived;
}

set_new_goodwill keyboard_arrow_up

Parameters help

Name Type
_new_goodwill
uint16 help

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlyOwner checks for the following:
null

Requirements help

Source Code
function set_new_goodwill(uint16 _new_goodwill) public onlyOwner {
  require(
    _new_goodwill >= 0 && _new_goodwill < 10000,
    "GoodWill Value not allowed"
  );
  goodwill = _new_goodwill;
}

inCaseTokengetsStuck keyboard_arrow_up

Parameters help

Name Type
_TokenAddress
IERC20 help

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlyOwner checks for the following:
null
Source Code
function inCaseTokengetsStuck(IERC20 _TokenAddress) public onlyOwner {
  uint256 qty = _TokenAddress.balanceOf(address(this));
  IERC20(address(_TokenAddress)).safeTransfer(owner(), qty);
}

toggleContractActive keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlyOwner checks for the following:
null
Source Code
function toggleContractActive() public onlyOwner {
  stopped = !stopped;
}

withdraw keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlyOwner checks for the following:
null
Source Code
function withdraw() public onlyOwner {
  uint256 contractBalance = address(this).balance;
  address payable _to = Address.toPayable(owner());
  _to.transfer(contractBalance);
}

constructor keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help payable

Requirements help

Source Code
function() external payable {
  require(msg.sender != tx.origin, "Do not send ETH directly");
}

Internal Functions Expand All Collapse All

Internal functions are parts of the contract that can't be used directly, but instead are used by the public functions listed above.

internal yVault_ZapInOut_General_V1_5._withdrawFromCurve keyboard_arrow_up

Parameters help

Name Type
_CurvePoolToken
address help
_tokenAmt
uint256 help
_toWhomToIssue
address help
_ToTokenContractAddress
address help
_minTokensRec
uint256 help

Properties

Visibility help internal
Mutability help transaction
Source Code
function _withdrawFromCurve(
  address _CurvePoolToken,
  uint256 _tokenAmt,
  address _toWhomToIssue,
  address _ToTokenContractAddress,
  uint256 _minTokensRec
) internal returns (uint256) {
  IERC20(_CurvePoolToken).safeApprove(address(CurveZapOutGeneral), _tokenAmt);

  address curveExchangeAddr = token2Exchange[_CurvePoolToken];

  return (
    CurveZapOutGeneral.ZapOut(
      Address.toPayable(_toWhomToIssue),
      curveExchangeAddr,
      _tokenAmt,
      _ToTokenContractAddress,
      _minTokensRec
    )
  );
}

internal yVault_ZapInOut_General_V1_5._eth2Token keyboard_arrow_up

Parameters help

Name Type
_tokenContractAddress
address help

Properties

Visibility help internal
Mutability help transaction
Source Code
function _eth2Token(address _tokenContractAddress)
  internal
  returns (uint256 tokensBought)
{
  if (_tokenContractAddress == wethTokenAddress) {
    IWETH(wethTokenAddress).deposit.value(msg.value)();
    return msg.value;
  }

  address[] memory path = new address[](2);
  path[0] = wethTokenAddress;
  path[1] = _tokenContractAddress;
  tokensBought = uniswapRouter.swapExactETHForTokens.value(msg.value)(
    1,
    path,
    address(this),
    deadline
  )[path.length - 1];
}

internal yVault_ZapInOut_General_V1_5._token2Token keyboard_arrow_up

Parameters help

Name Type
_FromTokenContractAddress
address help
_ToTokenContractAddress
address help
tokens2Trade
uint256 help

Properties

Visibility help internal
Mutability help transaction
Source Code
function _token2Token(
  address _FromTokenContractAddress,
  address _ToTokenContractAddress,
  uint256 tokens2Trade
) internal returns (uint256 tokenBought) {
  if (_FromTokenContractAddress == _ToTokenContractAddress) {
    return tokens2Trade;
  }

  IERC20(_FromTokenContractAddress).safeApprove(
    address(uniswapRouter),
    tokens2Trade
  );

  if (_FromTokenContractAddress != wethTokenAddress) {
    if (_ToTokenContractAddress != wethTokenAddress) {
      address[] memory path = new address[](3);
      path[0] = _FromTokenContractAddress;
      path[1] = wethTokenAddress;
      path[2] = _ToTokenContractAddress;
      tokenBought = uniswapRouter.swapExactTokensForTokens(
        tokens2Trade,
        1,
        path,
        address(this),
        deadline
      )[path.length - 1];
    } else {
      address[] memory path = new address[](2);
      path[0] = _FromTokenContractAddress;
      path[1] = wethTokenAddress;

      tokenBought = uniswapRouter.swapExactTokensForTokens(
        tokens2Trade,
        1,
        path,
        address(this),
        deadline
      )[path.length - 1];
    }
  } else {
    address[] memory path = new address[](2);
    path[0] = wethTokenAddress;
    path[1] = _ToTokenContractAddress;
    tokenBought = uniswapRouter.swapExactTokensForTokens(
      tokens2Trade,
      1,
      path,
      address(this),
      deadline
    )[path.length - 1];
  }
}

internal yVault_ZapInOut_General_V1_5._token2Eth keyboard_arrow_up

Parameters help

Name Type
_FromTokenContractAddress
address help
tokens2Trade
uint256 help
_toWhomToIssue
address help

Properties

Visibility help internal
Mutability help transaction
Source Code
function _token2Eth(
  address _FromTokenContractAddress,
  uint256 tokens2Trade,
  address payable _toWhomToIssue
) internal returns (uint256) {
  if (_FromTokenContractAddress == wethTokenAddress) {
    IWETH(wethTokenAddress).withdraw(tokens2Trade);
    _toWhomToIssue.transfer(tokens2Trade);
    return tokens2Trade;
  }

  IERC20(_FromTokenContractAddress).safeApprove(
    address(uniswapRouter),
    tokens2Trade
  );

  address[] memory path = new address[](2);
  path[0] = _FromTokenContractAddress;
  path[1] = wethTokenAddress;
  uint256 ethBought = uniswapRouter.swapExactTokensForETH(
    tokens2Trade,
    1,
    path,
    _toWhomToIssue,
    deadline
  )[path.length - 1];

  return ethBought;
}

internal yVault_ZapInOut_General_V1_5._transferGoodwill keyboard_arrow_up

Parameters help

Name Type
_tokenContractAddress
address help
tokens2Trade
uint256 help

Properties

Visibility help internal
Mutability help transaction
Source Code
function _transferGoodwill(address _tokenContractAddress, uint256 tokens2Trade)
  internal
  returns (uint256 goodwillPortion)
{
  goodwillPortion = SafeMath.div(SafeMath.mul(tokens2Trade, goodwill), 10000);

  if (goodwillPortion == 0) {
    return 0;
  }

  IERC20(_tokenContractAddress).safeTransfer(zgoodwillAddress, goodwillPortion);
}

internal ReentrancyGuard.constructor keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help internal
Mutability help transaction
Source Code
constructor() internal {
  // Storing an initial non-zero value makes deployment a bit more
  // expensive, but in exchange the refund on every call to nonReentrant
  // will be lower in amount. Since refunds are capped to a percetange of
  // the total transaction's gas, it is best to keep them low in cases
  // like this one, to increase the likelihood of the full refund coming
  // into effect.
  _notEntered = true;
}

internal Ownable.constructor keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help internal
Mutability help transaction
Source Code
constructor() internal {
  address payable msgSender = _msgSender();
  _owner = msgSender;
  emit OwnershipTransferred(address(0), msgSender);
}

internal Ownable._transferOwnership keyboard_arrow_up

Parameters help

Name Type
newOwner
address help

Properties

Visibility help internal
Mutability help transaction

Requirements help

Source Code
function _transferOwnership(address payable newOwner) internal {
  require(newOwner != address(0), "Ownable: new owner is the zero address");
  emit OwnershipTransferred(_owner, newOwner);
  _owner = newOwner;
}

internal Context.constructor keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help internal
Mutability help transaction
Source Code
constructor() internal {}

internal Context._msgSender keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help internal
Mutability help view
Source Code
function _msgSender() internal view returns (address payable) {
  return msg.sender;
}

internal Context._msgData keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help internal
Mutability help view
Source Code
function _msgData() internal view returns (bytes memory) {
  this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
  return msg.data;
}