Contract 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135

Txn Hash Method
Block
From
To
Value [Txn Fee]
0xed2002c61e52567f595a73f0b0ca6fd2af642dc4b9331d3d6645e204d4a72e73Swap ETH For Vau...234446512021-11-29 4:47:136 hrs 22 mins ago0x30de904e95673bbb03753af05dddf2f06d023a5d IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135148 FTM0.83107284587
0x7d9a8348505c2672256622614362d760d87746114ecb61da98500f6a4b742138Swap ETH For Vau...234085622021-11-28 20:00:3315 hrs 8 mins ago0x44954abef8f82b0a6bdea6d366f8a5ba5557a672 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec9313510.489 FTM2.080095682141
0x92f5d829d0987a0898f9764fccc30230ec28c584cd20e47c1b7c9d452109444fSwap ETH For Vau...234070362021-11-28 19:37:4515 hrs 31 mins ago0xf9aa2b8b6fc1ba884a10a677767cef449e529c72 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec9313566 FTM2.076452923228
0xc9992c3c4a95ad925eae9789ff0d4eff06f7e2c48cae381196961eba6481873cSwap ETH For Vau...234052192021-11-28 19:12:2815 hrs 56 mins ago0xa057a7d7183aa1e1cb9631fac587d47769fb300a IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931357,390 FTM3.298037265955
0x891d35d872db4c974f328dc8159c6ab2f95d6d784ac13c651a4a1843435e4d81Swap ETH For Vau...233977472021-11-28 17:08:1118 hrs 1 min ago0xad4f6aa05227ae792de0f73828b680f2baf71104 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931358,170 FTM1.859394513613
0x0839112981833ed8a1a6bc0e177a2217c5793187fb15629dcee6974a94e9f606Swap ETH For Vau...233954902021-11-28 16:30:2118 hrs 38 mins ago0xaf7e206e93ff4055e219ed6082a06058957b2828 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931351,320 FTM1.55392104266
0x3f74debdb88d834283ac35341c71dadf169d910e95edf6cce3b75b3c74435e1aSwap ETH For Vau...233944132021-11-28 16:15:3418 hrs 53 mins ago0xc81b62cb6a9af8d5f5e04d3934a3926aa89ed329 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931353,230 FTM1.735856585896
0x97aa2240acf34d84785d03b90c573013cb3cd692d8ebe2f3f2e360594285f423Swap ETH For Vau...233916552021-11-28 15:30:5919 hrs 38 mins ago0xc81b62cb6a9af8d5f5e04d3934a3926aa89ed329 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135500 FTM1.542648310619
0x47096bd5a5484920406ad136210b939a160c05465099c58f6fd3b0702a000b9eSwap ETH For Vau...233715362021-11-28 10:18:411 day 50 mins ago0xa1a33cb3023116ed2ec5e2baf77f9da74ca919cd IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135250 FTM0.828767867523
0x2b0b8d556a2053dfa5bdc6dcfe2fe7de6304d77c0cbf22d67b5db42d7a119b51Swap ETH For Vau...233615202021-11-28 7:52:301 day 3 hrs ago0x2a036b355fcfe50d9e1aef058b97190b74d47b63 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135150 FTM0.854308714175
0x3dc092d099d59b1b8e5be0464438fc5f54a4884fcb672f23c977bc9fabd5bf11Swap ETH For Vau...233549362021-11-28 6:15:361 day 4 hrs ago0x8b5a43ca240fb02debc43531cdaa44dff7ccbb82 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135200 FTM1.086648805879
0x83dc8e73c717a0c39002a6f6649364bf913355636df41dfd86035e999c869a65Swap ETH For Vau...233394832021-11-28 2:26:261 day 8 hrs ago0xb45c692d01442494b70a8c7e1d96905cc5d4cf3f IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135100 FTM1.333545585886
0x9d4ea7030f11f67bc9d92b147b9b2379cf875eb5f102514f4c9eb2fabf8bf239Swap ETH For Vau...233320262021-11-28 0:37:261 day 10 hrs ago0x1265a989b92bdcb9a5cb86d86f3701fca5514cb7 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135220 FTM0.76190798041
0xbc7ff6f923aecfa6758d81fe6ef20ff65b2ba1d62a750f8eaaf8663033f2427fSwap ETH For Vau...233294072021-11-28 0:00:281 day 11 hrs ago0xf9aa2b8b6fc1ba884a10a677767cef449e529c72 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec9313553 FTM0.850366281508
0x9a0b69bbbaa46ada1b803aff13feeb829f1e0e039c5366b7b0a3edd4164dd58eSwap ETH For Vau...233157612021-11-27 20:47:331 day 14 hrs ago0x44954abef8f82b0a6bdea6d366f8a5ba5557a672 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931358.722 FTM1.877020038121
0xf594c1937eb5281963c5b8bd85d79c72778a8a82d093d58f386d46eec5eda3d1Swap ETH For Vau...233156332021-11-27 20:45:421 day 14 hrs ago0x44954abef8f82b0a6bdea6d366f8a5ba5557a672 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec9313510.821 FTM0.098719338376
0xa74f5b31c332dd04bbe11dce3e836f3062e02aa3481dfce8d31fb08fadb186aeSwap ETH For Vau...233004352021-11-27 17:06:351 day 18 hrs ago0xaf7e206e93ff4055e219ed6082a06058957b2828 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135100 FTM1.294650191434
0x307c07a480fef2f4a8d57f4cce02daf1f986b9d933271271ce26dc52dfc7bdb6Swap ETH For Vau...233003402021-11-27 17:05:201 day 18 hrs ago0xaf7e206e93ff4055e219ed6082a06058957b2828 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135335 FTM1.284775038168
0xfbcc9cc2440dcf1a8e3e22cd082e81a9a0f979d4206e08ee49e8208905e42ff9Swap ETH For Vau...232837662021-11-27 13:01:381 day 22 hrs ago0x0a2d3dd46e44acec0da085268502880bb384bcc0 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec9313510 FTM0.866976491189
0x6969df509c92ec5cf4814406075ffe5ea90444f2083090c689907809d6ff16b0Swap ETH For Vau...232690242021-11-27 9:22:092 days 1 hr ago0x9a43e2d3f7d28f0bb8a6b5952dc563ab51b8cb55 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135500 FTM1.008587426565
0xd87e4a6d1338ea9b9adf22ab83e6d8488bda01f85f45be81a37bc380d9b7f6abSwap ETH For Vau...232679472021-11-27 9:01:562 days 2 hrs ago0x1265a989b92bdcb9a5cb86d86f3701fca5514cb7 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135450 FTM0.906040879335
0x8cd32a8d6f6b1e823dcc00c8221121f5f78de45a1844bab621c664866f1a34a5Swap ETH For Vau...232676082021-11-27 8:55:572 days 2 hrs ago0xf9aa2b8b6fc1ba884a10a677767cef449e529c72 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec9313549 FTM0.942413131135
0xdad518ab1ca7e8411f715c5ae734ec7f432825a442e8724fbac3e717ede8d733Swap ETH For Vau...232475972021-11-27 3:55:312 days 7 hrs ago0xf3d62360690120733ba14749f6904375c7d2d622 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931357,500 FTM1.581638023779
0x3525f99d8974b05d7081c39954bc9491eedc19682e537b32577b9c51d62131a8Swap ETH For Vau...232372152021-11-27 1:21:472 days 9 hrs ago0x44954abef8f82b0a6bdea6d366f8a5ba5557a672 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec9313524.035 FTM0.99199006775
0xecaeecba34f2aa63eba170b5a4cc6b00cfd3ac10990368aeb5e3bc22c0727cd8Swap ETH For Vau...232111762021-11-26 19:09:102 days 16 hrs ago0x1073a2e63fcbe9acb80b2fc3143a2717be188430 IN  0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec9313550 FTM1.714368453123
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xed2002c61e52567f595a73f0b0ca6fd2af642dc4b9331d3d6645e204d4a72e73234446512021-11-29 4:47:136 hrs 22 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931350x30de904e95673bbb03753af05dddf2f06d023a5d0.243558431897540862 FTM
0xed2002c61e52567f595a73f0b0ca6fd2af642dc4b9331d3d6645e204d4a72e73234446512021-11-29 4:47:136 hrs 22 mins ago Fantom Finance: Wrapped Fantom Token 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931350.243558431897540858 FTM
0xed2002c61e52567f595a73f0b0ca6fd2af642dc4b9331d3d6645e204d4a72e73234446512021-11-29 4:47:136 hrs 22 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token28.265194330636774588 FTM
0xed2002c61e52567f595a73f0b0ca6fd2af642dc4b9331d3d6645e204d4a72e73234446512021-11-29 4:47:136 hrs 22 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token30.724107020235468328 FTM
0xed2002c61e52567f595a73f0b0ca6fd2af642dc4b9331d3d6645e204d4a72e73234446512021-11-29 4:47:136 hrs 22 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token30.42622847495695645 FTM
0xed2002c61e52567f595a73f0b0ca6fd2af642dc4b9331d3d6645e204d4a72e73234446512021-11-29 4:47:136 hrs 22 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token28.661546819151140112 FTM
0xed2002c61e52567f595a73f0b0ca6fd2af642dc4b9331d3d6645e204d4a72e73234446512021-11-29 4:47:136 hrs 22 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token29.922923355019660518 FTM
0xed2002c61e52567f595a73f0b0ca6fd2af642dc4b9331d3d6645e204d4a72e73234446512021-11-29 4:47:136 hrs 22 mins ago 0x30de904e95673bbb03753af05dddf2f06d023a5d 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135148 FTM
0x7d9a8348505c2672256622614362d760d87746114ecb61da98500f6a4b742138234085622021-11-28 20:00:3315 hrs 8 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931350x44954abef8f82b0a6bdea6d366f8a5ba5557a6720.016650204328446378 FTM
0x7d9a8348505c2672256622614362d760d87746114ecb61da98500f6a4b742138234085622021-11-28 20:00:3315 hrs 8 mins ago Fantom Finance: Wrapped Fantom Token 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931350.016650204328446374 FTM
0x7d9a8348505c2672256622614362d760d87746114ecb61da98500f6a4b742138234085622021-11-28 20:00:3315 hrs 8 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token2.017871220312050119 FTM
0x7d9a8348505c2672256622614362d760d87746114ecb61da98500f6a4b742138234085622021-11-28 20:00:3315 hrs 8 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token2.2071131862736075 FTM
0x7d9a8348505c2672256622614362d760d87746114ecb61da98500f6a4b742138234085622021-11-28 20:00:3315 hrs 8 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token2.094824149759341649 FTM
0x7d9a8348505c2672256622614362d760d87746114ecb61da98500f6a4b742138234085622021-11-28 20:00:3315 hrs 8 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token2.04016365882451132 FTM
0x7d9a8348505c2672256622614362d760d87746114ecb61da98500f6a4b742138234085622021-11-28 20:00:3315 hrs 8 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token2.129027784830489408 FTM
0x7d9a8348505c2672256622614362d760d87746114ecb61da98500f6a4b742138234085622021-11-28 20:00:3315 hrs 8 mins ago 0x44954abef8f82b0a6bdea6d366f8a5ba5557a672 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec9313510.489 FTM
0x92f5d829d0987a0898f9764fccc30230ec28c584cd20e47c1b7c9d452109444f234070362021-11-28 19:37:4515 hrs 31 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931350xf9aa2b8b6fc1ba884a10a677767cef449e529c720.106380534216259377 FTM
0x92f5d829d0987a0898f9764fccc30230ec28c584cd20e47c1b7c9d452109444f234070362021-11-28 19:37:4515 hrs 31 mins ago Fantom Finance: Wrapped Fantom Token 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931350.106380534216259374 FTM
0x92f5d829d0987a0898f9764fccc30230ec28c584cd20e47c1b7c9d452109444f234070362021-11-28 19:37:4515 hrs 31 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token12.695134025793747891 FTM
0x92f5d829d0987a0898f9764fccc30230ec28c584cd20e47c1b7c9d452109444f234070362021-11-28 19:37:4515 hrs 31 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token13.888599007678248032 FTM
0x92f5d829d0987a0898f9764fccc30230ec28c584cd20e47c1b7c9d452109444f234070362021-11-28 19:37:4515 hrs 31 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token13.181483808465781257 FTM
0x92f5d829d0987a0898f9764fccc30230ec28c584cd20e47c1b7c9d452109444f234070362021-11-28 19:37:4515 hrs 31 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token12.834437893730561915 FTM
0x92f5d829d0987a0898f9764fccc30230ec28c584cd20e47c1b7c9d452109444f234070362021-11-28 19:37:4515 hrs 31 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec93135 Fantom Finance: Wrapped Fantom Token13.400345264331660902 FTM
0x92f5d829d0987a0898f9764fccc30230ec28c584cd20e47c1b7c9d452109444f234070362021-11-28 19:37:4515 hrs 31 mins ago 0xf9aa2b8b6fc1ba884a10a677767cef449e529c72 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec9313566 FTM
0xc9992c3c4a95ad925eae9789ff0d4eff06f7e2c48cae381196961eba6481873c234052192021-11-28 19:12:2815 hrs 56 mins ago 0xc8d8ccb89b4b2e64e057c5934ec4dadb0ec931350xa057a7d7183aa1e1cb9631fac587d47769fb300a37.101150135880816682 FTM
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BisharesZapUniswapRouterMinter

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 25000 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 20 : BisharesZapUniswapRouterMinter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/math/Math.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
import "../core/balancer/BNum.sol";
import "../interfaces/IWETH.sol";
import "../interfaces/IIndexPool.sol";
import "../interfaces/IBisharesUniswapV2Oracle.sol";
import "../interfaces/IVault.sol";
import "../interfaces/IStrategy.sol";
import "../interfaces/IZapUniswapV2.sol";
import "../lib/TransferHelper.sol";


contract BisharesZapUniswapRouterMinter is BNum {
  using SafeMath for uint256;
  using SafeERC20 for IERC20;

  address public immutable weth;
  IBisharesUniswapV2Oracle public immutable oracle;
  IZapUniswapV2 public immutable zapper;

  constructor(address weth_, address oracle_, address zapper_) {
    address zero = address(0);
    require(weth_ != zero, "BiShares: WETH is zero address");
    require(oracle_ != zero, "BiShares: Oracle is zero address");
    require(zapper_ != zero, "BiShares: Zapper is zero address");
    weth = weth_;
    oracle = IBisharesUniswapV2Oracle(oracle_);
    zapper = IZapUniswapV2(zapper_);
  }

  receive() external payable {
    require(msg.sender == weth, "BiShares: Received ether");
  }

  function swapETHForVaultsAndMint(
    address indexPool
  ) external payable returns (uint256 poolAmountOut) {
    address caller = msg.sender;
    uint256 initialAmount = msg.value;
    address this_ = address(this);
    (
      address[] memory vaults,
      address[] memory routers,
      uint256[] memory amountsIn
    ) = _getIndexPoolData(indexPool, initialAmount);
    poolAmountOut = _joinPool(indexPool, initialAmount, vaults, routers, amountsIn);
    TransferHelper.safeTransfer(indexPool, caller, poolAmountOut);
    uint256 wethBalance = IERC20(weth).balanceOf(this_);
    if (wethBalance > 0) IWETH(weth).withdraw(wethBalance);
    TransferHelper.safeTransferETH(caller, this_.balance);
  }

  function _joinPool(
    address indexPool,
    uint256 amountMax,
    address[] memory vaults,
    address[] memory routers,
    uint256[] memory amountsIn
  ) private returns (uint256 poolAmountOut) {
    poolAmountOut = uint256(-1);
    uint256[] memory amountsToPool = new uint256[](vaults.length);
    for (uint256 i = 0; i < vaults.length; i++) {
      (amountMax, amountsToPool[i], poolAmountOut) = _zapIn(
        indexPool,
        amountMax,
        poolAmountOut,
        amountsIn[i],
        routers[i],
        vaults[i]
      );
    }
    poolAmountOut = poolAmountOut.mul(999).div(1000);
    IIndexPool(indexPool).joinPool(poolAmountOut, amountsToPool);
    _zapOutVaultsToETH(vaults, routers);
  }

  function _zapIn(
    address indexPool,
    uint256 amountMax,
    uint256 poolAmountOut,
    uint256 amountIn,
    address router,
    address vault
  ) private returns (uint256, uint256, uint256) {
    address zapperAddress = address(zapper);
    IWETH(weth).deposit{value: amountIn}();
    TransferHelper.safeApprove(weth, zapperAddress, amountIn);
    amountMax = SafeMath.sub(amountMax, amountIn, "BiShares: Excessive input amount");
    uint256 amountToPool = zapper.zapIn(router, vault, amountIn, 1);
    TransferHelper.safeApprove(vault, indexPool, amountToPool);
    poolAmountOut = Math.min(
      poolAmountOut,
      bmul(
        bdiv(
          amountToPool,
          IIndexPool(indexPool).getTokenRecord(vault).balance
        ),
        IERC20(indexPool).totalSupply()
      )
    );
    address[] memory tokens = new address[](2);
    IStrategy strategy = IStrategy(IVault(vault).strategy());
    tokens[0] = strategy.lpToken0();
    tokens[1] = strategy.lpToken1();
    _returnAssets(tokens);
    return (amountMax, amountToPool, poolAmountOut);
  }

  function _getIndexPoolData(
    address indexPool,
    uint256 initialAmount
  ) private view returns (address[] memory vaults, address[] memory routers, uint256[] memory amountsIn) {
    address[] memory factories = IIndexPool(indexPool).factories();
    vaults = IIndexPool(indexPool).getCurrentTokens();
    routers = IIndexPool(indexPool).routers();
    uint256 length = vaults.length;
    amountsIn = new uint256[](length);
    uint256 sum = 0;
    for (uint256 i = 0; i < length; i++) {
      uint256 balanceInNative = oracle.computeAverageEthForTokens(
        factories[i],
        vaults[i],
        IIndexPool(indexPool).getBalance(vaults[i])
      );
      amountsIn[i] = balanceInNative;
      sum = sum.add(balanceInNative);
    }
    for (uint256 j = 0; j < length; j++) amountsIn[j] = amountsIn[j].mul(initialAmount).div(sum);
  }

  function _returnAssets(address[] memory tokens) private {
    address caller = msg.sender;
    address this_ = address(this);
    uint256 balance = 0;
    for (uint256 i; i < tokens.length; i++) {
      address token = tokens[i];
      balance = IERC20(token).balanceOf(this_);
      if (balance > 0) IERC20(token).safeTransfer(caller, balance);
    }
  }

  function _zapOutVaultsToETH(
    address[] memory vaults,
    address[] memory routers
  ) private returns (uint256 cumulativeAmount) {
    uint256 balance;
    address this_ = address(this);
    address zapperAddress = address(zapper);
    uint256 min = 1;
    for (uint256 i = 0; i < vaults.length; i++) {
      address vault = vaults[i];
      balance = IERC20(vault).balanceOf(this_);
      if (balance > 0) {
        TransferHelper.safeApprove(vault, zapperAddress, balance);
        cumulativeAmount += zapper.zapOut(routers[i], vault, balance, weth, min);
      }
    }
  }
}

File 2 of 20 : UniswapV2OracleLibrary.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

import "../interfaces/IUniswapV2Pair.sol";
import "./FixedPoint.sol";


library UniswapV2OracleLibrary {
  using FixedPoint for *;

  // helper function that returns the current block timestamp within the range of uint32, i.e. [0, 2**32 - 1]
  function currentBlockTimestamp() internal view returns (uint32) {
    return uint32(block.timestamp % 2**32);
  }

  function currentCumulativePrices(
    address pair
  ) internal view returns (uint256 price0Cumulative, uint256 price1Cumulative, uint32 blockTimestamp) {
    blockTimestamp = currentBlockTimestamp();
    price0Cumulative = IUniswapV2Pair(pair).price0CumulativeLast();
    price1Cumulative = IUniswapV2Pair(pair).price1CumulativeLast();
    (
      uint112 reserve0,
      uint112 reserve1,
      uint32 blockTimestampLast
    ) = IUniswapV2Pair(pair).getReserves();
    require(
      reserve0 != 0 && reserve1 != 0,
      "UniswapV2OracleLibrary::currentCumulativePrices: Pair has no reserves."
    );
    if (blockTimestampLast != blockTimestamp) {
      uint32 timeElapsed = blockTimestamp - blockTimestampLast;
      price0Cumulative += (
        uint256(FixedPoint.fraction(reserve1, reserve0)._x) *
        timeElapsed
      );
      price1Cumulative += (
        uint256(FixedPoint.fraction(reserve0, reserve1)._x) *
        timeElapsed
      );
    }
  }

  function currentCumulativePrice0(
    address pair
  ) internal view returns (uint256 price0Cumulative, uint32 blockTimestamp) {
    blockTimestamp = currentBlockTimestamp();
    price0Cumulative = IUniswapV2Pair(pair).price0CumulativeLast();
    (
      uint112 reserve0,
      uint112 reserve1,
      uint32 blockTimestampLast
    ) = IUniswapV2Pair(pair).getReserves();
    require(
      reserve0 != 0 && reserve1 != 0,
      "UniswapV2OracleLibrary::currentCumulativePrice0: Pair has no reserves."
    );
    if (blockTimestampLast != blockTimestamp) {
      uint32 timeElapsed = blockTimestamp - blockTimestampLast;
      price0Cumulative += (
        uint256(FixedPoint.fraction(reserve1, reserve0)._x) *
        timeElapsed
      );
    }
  }

  function currentCumulativePrice1(
    address pair
  ) internal view returns (uint256 price1Cumulative, uint32 blockTimestamp) {
    blockTimestamp = currentBlockTimestamp();
    price1Cumulative = IUniswapV2Pair(pair).price1CumulativeLast();
    (
      uint112 reserve0,
      uint112 reserve1,
      uint32 blockTimestampLast
    ) = IUniswapV2Pair(pair).getReserves();
    require(
      reserve0 != 0 && reserve1 != 0,
      "UniswapV2OracleLibrary::currentCumulativePrice1: Pair has no reserves."
    );
    if (blockTimestampLast != blockTimestamp) {
      uint32 timeElapsed = blockTimestamp - blockTimestampLast;
      price1Cumulative += (
        uint256(FixedPoint.fraction(reserve0, reserve1)._x) *
        timeElapsed
      );
    }
  }

  function computeAveragePrice(
    uint224 priceCumulativeStart,
    uint224 priceCumulativeEnd,
    uint32 timeElapsed
  ) internal pure returns (FixedPoint.uq112x112 memory priceAverage) {
    priceAverage = FixedPoint.uq112x112(
      uint224((priceCumulativeEnd - priceCumulativeStart) / timeElapsed)
    );
  }
}

File 3 of 20 : UniswapV2Library.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

import "@openzeppelin/contracts/math/SafeMath.sol";
import "../interfaces/IUniswapV2Pair.sol";


interface IUniswapFactory {
    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);
    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);
    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

library UniswapV2Library {
  using SafeMath for uint256;

  function sortTokens(
    address tokenA,
    address tokenB
  ) internal pure returns (address token0, address token1) {
    require(tokenA != tokenB, "UniswapV2Library: IDENTICAL_ADDRESSES");
    (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
    require(token0 != address(0), "UniswapV2Library: ZERO_ADDRESS");
  }

  function calculatePair(
    address factory,
    address token0,
    address token1
  ) internal view returns (address pair) {
    IUniswapFactory _factory = IUniswapFactory(factory);
    pair = _factory.getPair(token0, token1);
  }

  function pairFor(
    address factory,
    address tokenA,
    address tokenB
  ) internal view returns (address pair) {
    (address token0, address token1) = sortTokens(tokenA, tokenB);
    pair = calculatePair(factory, token0, token1);
  }

  function getReserves(
    address factory,
    address tokenA,
    address tokenB
  ) internal view returns (uint256 reserveA, uint256 reserveB) {
    (address token0, ) = sortTokens(tokenA, tokenB);
    (uint256 reserve0, uint256 reserve1, ) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB)).getReserves();
    (reserveA, reserveB) = tokenA == token0
      ? (reserve0, reserve1)
      : (reserve1, reserve0);
  }

  function quote(
    uint256 amountA,
    uint256 reserveA,
    uint256 reserveB
  ) internal pure returns (uint256 amountB) {
    require(amountA > 0, "UniswapV2Library: INSUFFICIENT_AMOUNT");
    require(
      reserveA > 0 && reserveB > 0,
      "UniswapV2Library: INSUFFICIENT_LIQUIDITY"
    );
    amountB = amountA.mul(reserveB) / reserveA;
  }

  function getAmountOut(
    uint256 amountIn,
    uint256 reserveIn,
    uint256 reserveOut
  ) internal pure returns (uint256 amountOut) {
    require(amountIn > 0, "UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT");
    require(
      reserveIn > 0 && reserveOut > 0,
      "UniswapV2Library: INSUFFICIENT_LIQUIDITY"
    );
    uint256 amountInWithFee = amountIn.mul(997);
    uint256 numerator = amountInWithFee.mul(reserveOut);
    uint256 denominator = reserveIn.mul(1000).add(amountInWithFee);
    amountOut = numerator / denominator;
  }

  function getAmountIn(
    uint256 amountOut,
    uint256 reserveIn,
    uint256 reserveOut
  ) internal pure returns (uint256 amountIn) {
    require(amountOut > 0, "UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT");
    require(
      reserveIn > 0 && reserveOut > 0,
      "UniswapV2Library: INSUFFICIENT_LIQUIDITY"
    );
    uint256 numerator = reserveIn.mul(amountOut).mul(1000);
    uint256 denominator = reserveOut.sub(amountOut).mul(997);
    amountIn = (numerator / denominator).add(1);
  }

  function getAmountsOut(
    address factory,
    uint256 amountIn,
    address[] memory path
  ) internal view returns (uint256[] memory amounts) {
    require(path.length >= 2, "UniswapV2Library: INVALID_PATH");
    amounts = new uint256[](path.length);
    amounts[0] = amountIn;
    for (uint256 i; i < path.length - 1; i++) {
      (uint256 reserveIn, uint256 reserveOut) = getReserves(factory, path[i], path[i + 1]);
      amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
    }
  }

  function getAmountsIn(
    address factory,
    uint256 amountOut,
    address[] memory path
  ) internal view returns (uint256[] memory amounts) {
    require(path.length >= 2, "UniswapV2Library: INVALID_PATH");
    amounts = new uint256[](path.length);
    amounts[amounts.length - 1] = amountOut;
    for (uint256 i = path.length - 1; i > 0; i--) {
      (uint256 reserveIn, uint256 reserveOut) = getReserves(factory, path[i - 1], path[i]);
      amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
    }
  }
}

File 4 of 20 : TransferHelper.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
    function safeApprove(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');
    }

    function safeTransfer(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
    }

    function safeTransferFrom(address token, address from, address to, uint value) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
    }

    function safeTransferETH(address to, uint value) internal {
        (bool success,) = to.call{value:value}(new bytes(0));
        require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
    }
}

File 5 of 20 : PriceLibrary.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/math/SafeMath.sol";
import "./FixedPoint.sol";
import "./UniswapV2OracleLibrary.sol";
import "./UniswapV2Library.sol";
import "../interfaces/IVault.sol";


library PriceLibrary {
  using SafeMath for uint256;
  using FixedPoint for FixedPoint.uq112x112;
  using FixedPoint for FixedPoint.uq144x112;

  uint256 private constant PRECISION = 1e18;

  struct PriceObservation {
    uint32 timestamp;
    uint224 priceCumulativeLast;
    uint224 ethPriceCumulativeLast;
  }

  struct TwoWayAveragePrice {
    uint224 priceAverage;
    uint224 ethPriceAverage;
  }

  function computeAverageEthForTokens(
    PriceLibrary.TwoWayAveragePrice memory prices,
    uint256 tokenAmount
  ) internal pure returns (uint144) {
    return FixedPoint.uq112x112(prices.priceAverage).mul(tokenAmount).decode144();
  }

  function computeAverageTokensForEth(
    PriceLibrary.TwoWayAveragePrice memory prices,
    uint256 wethAmount
  ) internal pure returns (uint144) {
    return FixedPoint.uq112x112(prices.ethPriceAverage).mul(wethAmount).decode144();
  }

  function pairInitialized(
    address uniswapFactory,
    address token,
    address weth
  ) internal view returns (bool isInitialized) {
    IUniswapFactory factory = IUniswapFactory(uniswapFactory);
    IUniswapV2Pair vaultLP = IUniswapV2Pair(address(IVault(token).token()));
		isInitialized = _checkPairReserves(factory, vaultLP.token0(), weth);
		if (!isInitialized) {
			isInitialized = _checkPairReserves(factory, vaultLP.token1(), weth);
		}
  }

  function observePrice(
    address uniswapFactory,
    address tokenIn,
    address quoteToken,
		bool reversed
  ) internal view returns (uint32 timestamp, uint224 priceCumulativeLast) {
    uint256 lpReservesInQuote;
    (tokenIn, quoteToken) = reversed ? (quoteToken, tokenIn) : (tokenIn, quoteToken);
    IVault vault = IVault(tokenIn);
    IUniswapV2Pair vaultLP = IUniswapV2Pair(address(vault.token()));
    uint256 vaultPrice = vault.getPricePerFullShare();
    uint256 vaultLPTotalSupply = vaultLP.totalSupply();
    (timestamp, lpReservesInQuote) = _calculateVaultLPReservesInQuote(
      uniswapFactory,
      vaultLP,
      quoteToken
    );
    priceCumulativeLast = reversed
      ? _calculatePriceCumulativeLast(vaultLPTotalSupply, lpReservesInQuote, PRECISION, vaultPrice)
      : _calculatePriceCumulativeLast(lpReservesInQuote, vaultLPTotalSupply, vaultPrice, PRECISION);
  }

  function observeTwoWayPrice(
    address uniswapFactory,
    address token,
    address weth
  ) internal view returns (PriceLibrary.PriceObservation memory) {
    IVault vault = IVault(token);
    IUniswapV2Pair vaultLP = IUniswapV2Pair(address(vault.token()));
    uint256 vaultPrice = vault.getPricePerFullShare();
    uint256 vaultLPTotalSupply = vaultLP.totalSupply();
    (uint32 blockTimestamp, uint256 lpReservesInQuote) = _calculateVaultLPReservesInQuote(
      uniswapFactory,
      vaultLP,
      weth
    );
		return PriceLibrary.PriceObservation({
			timestamp: blockTimestamp,
			priceCumulativeLast: _calculatePriceCumulativeLast(
        lpReservesInQuote,
        vaultLPTotalSupply,
        vaultPrice,
        PRECISION
      ),
			ethPriceCumulativeLast: _calculatePriceCumulativeLast(
        vaultLPTotalSupply,
        lpReservesInQuote,
        PRECISION,
        vaultPrice
      )
		});
  }

  function _isLPReady(address token0, address token1, address quote) private pure returns (bool) {
    return quote == token1 || quote == token0; 
  }

  function _calculatePriceCumulativeLast(
    uint256 rateNominator,
    uint256 rateDenominator,
    uint256 rateMultiplier,
    uint256 rateDivider
  ) private pure returns (uint224 priceCumulativeLast) {
    uint256 rate = rateNominator.mul(PRECISION).div(rateDenominator);
    priceCumulativeLast = uint224(rate.mul(rateMultiplier).div(rateDivider).mul(2 ** 112).div(PRECISION));
  }

  function _calculateReservesForPrice(
    address factory,
    address token0,
    address token1,
    address quote
  ) private view returns (bool isToken0, uint256 tokenReserve, uint256 quoteReserve) {
    uint256 token0Reserve = 0;
    uint256 quoteReserve0 = 0;
    uint256 token1Reserve = 0;
    uint256 quoteReserve1 = 0;
    address zero = address(0);
    if (UniswapV2Library.pairFor(factory, token0, quote) != zero) {
      (token0Reserve, quoteReserve0) = UniswapV2Library.getReserves(factory, token0, quote);
    }
    if (UniswapV2Library.pairFor(factory, token1, quote) != zero) {
      (token1Reserve, quoteReserve1) = UniswapV2Library.getReserves(factory, token1, quote);
    }
    isToken0 = quoteReserve0 > quoteReserve1;
    if (isToken0) {
      tokenReserve = token0Reserve;
      quoteReserve = quoteReserve0;
    } else {
      tokenReserve = token1Reserve;
      quoteReserve = quoteReserve1;
    }
  }

  function _calculateVaultLPReservesInQuote(
    address factory,
    IUniswapV2Pair vaultLP,
    address quote
  ) private view returns (uint32 timestamp, uint256 lpReservesInQuote) {
    address token0 = vaultLP.token0();
    address token1 = vaultLP.token1();
    uint112 vaultLPReserve0;
    uint112 vaultLPReserve1;
    (vaultLPReserve0, vaultLPReserve1, timestamp) = vaultLP.getReserves();
    if (_isLPReady(token0, token1, quote)) {
      lpReservesInQuote = uint256(
        vaultLP.token0() == quote
          ? vaultLPReserve0
          : vaultLPReserve1
      ).mul(2);
    } else {
      (bool isToken0, uint256 tokenReserve, uint256 quoteReserve) = _calculateReservesForPrice(
        factory,
        token0,
        token1,
        quote
      );
      uint256 tokenToQuotePrice = quoteReserve.mul(PRECISION).div(tokenReserve);
      lpReservesInQuote = uint256(isToken0 ? vaultLPReserve0 : vaultLPReserve1)
        .mul(tokenToQuotePrice)
        .mul(2)
        .div(PRECISION);
    }
  }

	function _checkPairReserves(
		IUniswapFactory factory,
		address token,
		address quoteToken
	) private view returns (bool isPositiveReserve) {
		if (token != quoteToken) {
			address pair = factory.getPair(token, quoteToken);
			(uint112 reserve0, uint112 reserve1,) = IUniswapV2Pair(pair).getReserves();
			isPositiveReserve = reserve0 != 0 && reserve1 != 0;
		}
	}

}

File 6 of 20 : FixedPoint.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;


library FixedPoint {
  // range: [0, 2**112 - 1]
  // resolution: 1 / 2**112
  struct uq112x112 {
    uint224 _x;
  }

  // range: [0, 2**144 - 1]
  // resolution: 1 / 2**112
  struct uq144x112 {
    uint256 _x;
  }

  uint8 private constant RESOLUTION = 112;
  uint256 private constant Q112 = uint256(1) << RESOLUTION;
  uint256 private constant Q224 = Q112 << RESOLUTION;

  function encode(uint112 x) internal pure returns (uq112x112 memory) {
    return uq112x112(uint224(x) << RESOLUTION);
  }

  function encode144(uint144 x) internal pure returns (uq144x112 memory) {
    return uq144x112(uint256(x) << RESOLUTION);
  }

  function div(uq112x112 memory self, uint112 x) internal pure returns (uq112x112 memory) {
    require(x != 0, "FixedPoint: DIV_BY_ZERO");
    return uq112x112(self._x / uint224(x));
  }

  function mul(uq112x112 memory self, uint256 y) internal pure returns (uq144x112 memory) {
    uint256 z;
    require(
      y == 0 || (z = uint256(self._x) * y) / y == uint256(self._x),
      "FixedPoint: MULTIPLICATION_OVERFLOW"
    );
    return uq144x112(z);
  }

  function fraction(uint112 numerator, uint112 denominator) internal pure returns (uq112x112 memory) {
    require(denominator > 0, "FixedPoint: DIV_BY_ZERO");
    return uq112x112((uint224(numerator) << RESOLUTION) / denominator);
  }

  function decode(uq112x112 memory self) internal pure returns (uint112) {
    return uint112(self._x >> RESOLUTION);
  }

  function decode144(uq144x112 memory self) internal pure returns (uint144) {
    return uint144(self._x >> RESOLUTION);
  }

  function reciprocal(uq112x112 memory self) internal pure returns (uq112x112 memory) {
    require(self._x != 0, "FixedPoint: ZERO_RECIPROCAL");
    return uq112x112(uint224(Q224 / self._x));
  }
}

File 7 of 20 : IZapUniswapV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;


interface IZapUniswapV2 {
    function zapIn(
        address router,
        address vault,
        uint256 valueAmount,
        uint256 vaultAmountOutMin
    ) external returns (uint256 vaultAmount);

    function zapOut(
        address router,
        address vault,
        uint256 withdrawAmount,
        address desiredToken,
        uint256 desiredTokenOutMin
    ) external returns (uint256 desiredTokenAmount);
}

File 8 of 20 : IWETH.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;


interface IWETH {
    function deposit() external payable;
    function transfer(address to, uint256 value) external returns (bool);
    function withdraw(uint256) external;
}

File 9 of 20 : IVault.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

import '@openzeppelin/contracts/token/ERC20/IERC20.sol';


interface IVault is IERC20 {
    function getPricePerFullShare() external view returns (uint256);
    function token() external view returns (IERC20);
    function strategy() external view returns (address);

    function deposit(uint256 amount) external returns (bool);
    function withdraw(uint256 shares) external returns (bool);
}

File 10 of 20 : IUniswapV2Pair.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);
    function swapFee() external view returns (uint); // Biswap support

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

File 11 of 20 : IStrategy.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";


interface IStrategy {
    function balanceOf() external view returns (uint256);
    function lpToken0() external view returns (address);
    function lpToken1() external view returns (address);

    function deposit() external returns (bool);
    function withdraw(uint256 _amount) external returns (bool);
    function retireStrat() external returns (bool);
    function harvest() external returns (bool);
}

File 12 of 20 : IIndexPool.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
pragma experimental ABIEncoderV2;


interface IIndexPool {
  /**
   * @dev Token record data structure
   * @param bound is token bound to pool
   * @param ready has token been initialized
   * @param lastDenormUpdate timestamp of last denorm change
   * @param denorm denormalized weight
   * @param desiredDenorm desired denormalized weight (used for incremental changes)
   * @param index index of address in tokens array
   * @param balance token balance
   */
  struct Record {
    bool bound;
    bool ready;
    uint40 lastDenormUpdate;
    uint96 denorm;
    uint96 desiredDenorm;
    uint8 index;
    uint256 balance;
  }

  function configure(
    address controller,
    string memory name,
    string memory symbol,
    address[] memory uniswapV2Factories,
    address[] memory uniswapV2Routers,
    address uniswapV2Oracle
  ) external returns (bool);
  function initialize(
    address[] memory tokens,
    uint256[] memory balances,
    uint96[] memory denorms,
    address tokenProvider
  ) external returns (bool);
  function setMaxPoolTokens(uint256 maxPoolTokens) external returns (bool);
  function delegateCompLikeToken(address token, address delegatee) external returns (bool);
  function reweighTokens(
    address[] memory tokens,
    uint96[] memory desiredDenorms
  ) external returns (bool);
  function reindexTokens(
    address[] memory tokens,
    uint96[] memory desiredDenorms,
    uint256[] memory minimumBalances
  ) external returns (bool);
  function setMinimumBalance(address token, uint256 minimumBalance) external returns (bool);
  function joinPool(uint256 poolAmountOut, uint256[] memory maxAmountsIn) external returns (bool);
  function exitPool(uint256 poolAmountIn, uint256[] memory minAmountsOut) external returns (bool);

  function oracle() external view returns (address);
  function routers() external view returns (address[] memory);
  function factories() external view returns (address[] memory);
  function isPublicSwap() external view returns (bool);
  function getController() external view returns (address);
  function getMaxPoolTokens() external view returns (uint256);
  function isBound(address t) external view returns (bool);
  function getNumTokens() external view returns (uint256);
  function getCurrentTokens() external view returns (address[] memory);
  function getCurrentDesiredTokens() external view returns (address[] memory tokens);
  function getDenormalizedWeight(address token) external view returns (uint256);
  function getTokenRecord(address token) external view returns (Record memory record);
  function extrapolatePoolValueFromToken() external view returns (address, address, uint256);
  function getTotalDenormalizedWeight() external view returns (uint256);
  function getBalance(address token) external view returns (uint256);
  function getMinimumBalance(address token) external view returns (uint256);
  function getUsedBalance(address token) external view returns (uint256);
}

File 13 of 20 : IBisharesUniswapV2Oracle.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
pragma experimental ABIEncoderV2;

import "../lib/PriceLibrary.sol";
import "../lib/FixedPoint.sol";


interface IBisharesUniswapV2Oracle {
  function computeTwoWayAveragePrice(
    address factory,
		address token
  ) external view returns (PriceLibrary.TwoWayAveragePrice memory);
  function computeAverageTokenPrice(
    address factory,
		address token
  ) external view returns (FixedPoint.uq112x112 memory);
  function computeAverageEthPrice(
    address factory,
		address token
  ) external view returns (FixedPoint.uq112x112 memory);
  function computeTwoWayAveragePrices(
		address[] memory factories,
    address[] memory tokens
  ) external view returns (PriceLibrary.TwoWayAveragePrice[] memory);
  function computeAverageTokenPrices(
		address[] memory factories,
    address[] memory tokens
  ) external view returns (FixedPoint.uq112x112[] memory);
  function computeAverageEthPrices(
		address[] memory factories,
    address[] memory tokens
  ) external view returns (FixedPoint.uq112x112[] memory);
  function computeAverageEthForTokens(
    address factory,
    address token,
    uint256 tokenAmount
  ) external view returns (uint144);
  function computeAverageTokensForEth(
    address factory,
    address token,
    uint256 wethAmount
  ) external view returns (uint144);
  function computeAverageEthForTokens(
		address[] memory factories,
    address[] memory tokens,
    uint256[] memory tokenAmounts
  ) external view returns (uint144[] memory);
  function computeAverageTokensForEth(
		address[] memory factories,
    address[] memory tokens,
    uint256[] memory wethAmounts
  ) external view returns (uint144[] memory);
}

File 14 of 20 : BNum.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

import "./BConst.sol";


contract BNum is BConst {
  function btoi(uint256 a) internal pure returns (uint256) {
    return a / BONE;
  }

  function bfloor(uint256 a) internal pure returns (uint256) {
    return btoi(a) * BONE;
  }

  function badd(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a, "BiShares: Add overflow");
    return c;
  }

  function bsub(uint256 a, uint256 b) internal pure returns (uint256) {
    (uint256 c, bool flag) = bsubSign(a, b);
    require(!flag, "BiShares: Sub overflow");
    return c;
  }

  function bsubSign(uint256 a, uint256 b)
    internal
    pure
    returns (uint256, bool)
  {
    if (a >= b) {
      return (a - b, false);
    } else {
      return (b - a, true);
    }
  }

  function bmul(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c0 = a * b;
    require(a == 0 || c0 / a == b, "BiShares: Mul overflow");
    uint256 c1 = c0 + (BONE / 2);
    require(c1 >= c0, "BiShares: Mul overflow");
    uint256 c2 = c1 / BONE;
    return c2;
  }

  function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0, "BiShares: Div zero");
    uint256 c0 = a * BONE;
    require(a == 0 || c0 / a == BONE, "BiShares: Div overflow");
    uint256 c1 = c0 + (b / 2);
    require(c1 >= c0, "BiShares: Div overflow");
    uint256 c2 = c1 / b;
    return c2;
  }

  function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {
    uint256 z = n % 2 != 0 ? a : BONE;
    for (n /= 2; n != 0; n /= 2) {
      a = bmul(a, a);
      if (n % 2 != 0) {
        z = bmul(z, a);
      }
    }
    return z;
  }

  function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {
    require(base >= MIN_BPOW_BASE, "BiShares: Bpow base too low");
    require(base <= MAX_BPOW_BASE, "BiShares: Bpow base too high");
    uint256 whole = bfloor(exp);
    uint256 remain = bsub(exp, whole);
    uint256 wholePow = bpowi(base, btoi(whole));
    if (remain == 0) {
      return wholePow;
    }
    uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);
    return bmul(wholePow, partialResult);
  }

  function bpowApprox(
    uint256 base,
    uint256 exp,
    uint256 precision
  ) internal pure returns (uint256) {
    uint256 a = exp;
    (uint256 x, bool xneg) = bsubSign(base, BONE);
    uint256 term = BONE;
    uint256 sum = term;
    bool negative = false;
    for (uint256 i = 1; term >= precision; i++) {
      uint256 bigK = i * BONE;
      (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));
      term = bmul(term, bmul(c, x));
      term = bdiv(term, bigK);
      if (term == 0) break;
      if (xneg) negative = !negative;
      if (cneg) negative = !negative;
      if (negative) {
        sum = bsub(sum, term);
      } else {
        sum = badd(sum, term);
      }
    }
    return sum;
  }
}

File 15 of 20 : BConst.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;


contract BConst {
  uint256 internal constant WEIGHT_UPDATE_DELAY = 1 hours;
  uint256 internal constant WEIGHT_CHANGE_PCT = BONE / 100;
  uint256 internal constant BONE = 10**18;
  uint256 internal constant MIN_BOUND_TOKENS = 2;
  uint256 internal constant MAX_BOUND_TOKENS = 25;
  uint256 internal constant EXIT_FEE = 0;
  uint256 internal constant MIN_WEIGHT = BONE / 8;
  uint256 internal constant MAX_WEIGHT = BONE * 25;
  uint256 internal constant MAX_TOTAL_WEIGHT = BONE * 26;
  uint256 internal constant MIN_BALANCE = BONE / 10**12;
  uint256 internal constant INIT_POOL_SUPPLY = BONE * 100;
  uint256 internal constant MIN_BPOW_BASE = 1 wei;
  uint256 internal constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;
  uint256 internal constant BPOW_PRECISION = BONE / 10**10;
}

File 16 of 20 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 17 of 20 : SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 18 of 20 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (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.
     */
    function transfer(address recipient, uint256 amount) external returns (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.
     */
    function allowance(address owner, address spender) external view returns (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.
     */
    function approve(address spender, uint256 amount) external returns (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.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed 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.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 19 of 20 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

File 20 of 20 : Math.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": true,
    "runs": 25000
  },
  "evmVersion": "berlin",
  "libraries": {},
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"weth_","type":"address"},{"internalType":"address","name":"oracle_","type":"address"},{"internalType":"address","name":"zapper_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract IBisharesUniswapV2Oracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"indexPool","type":"address"}],"name":"swapETHForVaultsAndMint","outputs":[{"internalType":"uint256","name":"poolAmountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"zapper","outputs":[{"internalType":"contract IZapUniswapV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60e06040523480156200001157600080fd5b506040516200263138038062002631833981016040819052620000349162000118565b60006001600160a01b038416620000685760405162461bcd60e51b81526004016200005f90620001cb565b60405180910390fd5b806001600160a01b0316836001600160a01b031614156200009d5760405162461bcd60e51b81526004016200005f9062000161565b806001600160a01b0316826001600160a01b03161415620000d25760405162461bcd60e51b81526004016200005f9062000196565b506001600160601b0319606093841b811660805291831b821660a05290911b1660c05262000202565b80516001600160a01b03811681146200011357600080fd5b919050565b6000806000606084860312156200012d578283fd5b6200013884620000fb565b92506200014860208501620000fb565b91506200015860408501620000fb565b90509250925092565b6020808252818101527f42695368617265733a204f7261636c65206973207a65726f2061646472657373604082015260600190565b6020808252818101527f42695368617265733a205a6170706572206973207a65726f2061646472657373604082015260600190565b6020808252601e908201527f42695368617265733a2057455448206973207a65726f20616464726573730000604082015260600190565b60805160601c60a05160601c60c05160601c6123c36200026e600039806101865280610e1a5280610f2d5280611362528061144452508061016252806105bd5250806060528061013e528061021a52806102e45280610e3d5280610ec1528061149652506123c36000f3fe6080604052600436106100435760003560e01c80633fc8cef3146100c75780637dc0d1d0146100f2578063a7a2171214610107578063dd5e4bbf1461011c576100c2565b366100c2573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100b790612223565b60405180910390fd5b005b600080fd5b3480156100d357600080fd5b506100dc61013c565b6040516100e9919061215b565b60405180910390f35b3480156100fe57600080fd5b506100dc610160565b34801561011357600080fd5b506100dc610184565b61012f61012a366004611f6d565b6101a8565b6040516100e9919061225a565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60003334308380806101ba8886610379565b9250925092506101cd88868585856107d2565b96506101da888789610988565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a082319061024f90889060040161215b565b60206040518083038186803b15801561026757600080fd5b505afa15801561027b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029f9190612143565b9050801561034c576040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632e1a7d4d9061031990849060040161225a565b600060405180830381600087803b15801561033357600080fd5b505af1158015610347573d6000803e3d6000fd5b505050505b61036d878673ffffffffffffffffffffffffffffffffffffffff1631610b64565b50505050505050919050565b606080606060008573ffffffffffffffffffffffffffffffffffffffff1663fe5b38e46040518163ffffffff1660e01b815260040160006040518083038186803b1580156103c657600080fd5b505afa1580156103da573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526104209190810190611fa5565b90508573ffffffffffffffffffffffffffffffffffffffff1663cc77828d6040518163ffffffff1660e01b815260040160006040518083038186803b15801561046857600080fd5b505afa15801561047c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526104c29190810190611fa5565b93508573ffffffffffffffffffffffffffffffffffffffff1663aeb8fbf96040518163ffffffff1660e01b815260040160006040518083038186803b15801561050a57600080fd5b505afa15801561051e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105649190810190611fa5565b84519093508067ffffffffffffffff8111801561058057600080fd5b506040519080825280602002602001820160405280156105aa578160200160208202803683370190505b5092506000805b8281101561076c5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fe0101c986848151811061060357fe5b60200260200101518a858151811061061757fe5b60200260200101518d73ffffffffffffffffffffffffffffffffffffffff1663f8b2cb4f8d888151811061064757fe5b60200260200101516040518263ffffffff1660e01b815260040161066b919061215b565b60206040518083038186803b15801561068357600080fd5b505afa158015610697573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106bb9190612143565b6040518463ffffffff1660e01b81526004016106d99392919061217c565b60206040518083038186803b1580156106f157600080fd5b505afa158015610705573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107299190612111565b71ffffffffffffffffffffffffffffffffffff1690508086838151811061074c57fe5b60209081029190910101526107618382610ca1565b9250506001016105b1565b5060005b828110156107c7576107a8826107a28a88858151811061078c57fe5b6020026020010151610d1e90919063ffffffff16565b90610d91565b8582815181106107b457fe5b6020908102919091010152600101610770565b505050509250925092565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9060009067ffffffffffffffff8111801561080f57600080fd5b50604051908082528060200260200182016040528015610839578160200160208202803683370190505b50905060005b85518110156108b65761088f88888587858151811061085a57fe5b602002602001015189868151811061086e57fe5b60200260200101518b878151811061088257fe5b6020026020010151610e12565b84848151811061089b57fe5b6020908102919091010191909152909750925060010161083f565b506108c96103e86107a2846103e7610d1e565b6040517f4f69c0d400000000000000000000000000000000000000000000000000000000815290925073ffffffffffffffffffffffffffffffffffffffff881690634f69c0d4906109209085908590600401612263565b602060405180830381600087803b15801561093a57600080fd5b505af115801561094e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109729190612052565b5061097d858561135c565b505095945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251825160009485949389169392918291908083835b60208310610a5d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a20565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610abf576040519150601f19603f3d011682016040523d82523d6000602084013e610ac4565b606091505b5091509150818015610af2575080511580610af25750808060200190516020811015610aef57600080fd5b50515b610b5d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015290519081900360640190fd5b5050505050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040518082805190602001908083835b60208310610bdb57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114610c3d576040519150601f19603f3d011682016040523d82523d6000602084013e610c42565b606091505b5050905080610c9c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806123416023913960400191505060405180910390fd5b505050565b600082820183811015610d1557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600082610d2d57506000610d18565b82820282848281610d3a57fe5b0414610d15576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806123206021913960400191505060405180910390fd5b6000808211610e0157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381610e0a57fe5b049392505050565b6000806000807f000000000000000000000000000000000000000000000000000000000000000090507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0886040518263ffffffff1660e01b81526004016000604051808303818588803b158015610ea357600080fd5b505af1158015610eb7573d6000803e3d6000fd5b5050505050610ee77f00000000000000000000000000000000000000000000000000000000000000008289611541565b610f2789886040518060400160405280602081526020017f42695368617265733a2045786365737369766520696e70757420616d6f756e74815250611716565b985060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633c3b1ef688888b60016040518563ffffffff1660e01b8152600401610f8b94939291906121ed565b602060405180830381600087803b158015610fa557600080fd5b505af1158015610fb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdd9190612143565b9050610fea868c83611541565b61110f8961110a611087848f73ffffffffffffffffffffffffffffffffffffffff166364c7d6618c6040518263ffffffff1660e01b815260040161102e919061215b565b60e06040518083038186803b15801561104657600080fd5b505afa15801561105a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107e919061206c565b60c001516117cc565b8e73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110cd57600080fd5b505afa1580156110e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111059190612143565b611958565b611a68565b604080516002808252606082018352929b50600092909160208301908036833701905050905060008773ffffffffffffffffffffffffffffffffffffffff1663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b15801561117d57600080fd5b505afa158015611191573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111b59190611f89565b90508073ffffffffffffffffffffffffffffffffffffffff16635ee167c06040518163ffffffff1660e01b815260040160206040518083038186803b1580156111fd57600080fd5b505afa158015611211573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112359190611f89565b8260008151811061124257fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1663877562b66040518163ffffffff1660e01b815260040160206040518083038186803b1580156112c257600080fd5b505afa1580156112d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fa9190611f89565b8260018151811061130757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505061134a82611a7e565b50999b909a5097985050505050505050565b600080307f00000000000000000000000000000000000000000000000000000000000000006001835b875181101561153657600088828151811061139c57fe5b602002602001015190508073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b81526004016113df919061215b565b60206040518083038186803b1580156113f757600080fd5b505afa15801561140b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142f9190612143565b9550851561152d57611442818588611541565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e4e7f8ba89848151811061148a57fe5b602002602001015183897f0000000000000000000000000000000000000000000000000000000000000000886040518663ffffffff1660e01b81526004016114d69594939291906121ad565b602060405180830381600087803b1580156114f057600080fd5b505af1158015611504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115289190612143565b870196505b50600101611385565b505050505092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001781529251825160009485949389169392918291908083835b6020831061161657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016115d9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611678576040519150601f19603f3d011682016040523d82523d6000602084013e61167d565b606091505b50915091508180156116ab5750805115806116ab57508080602001905160208110156116a857600080fd5b50515b610b5d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f5472616e7366657248656c7065723a20415050524f56455f4641494c45440000604482015290519081900360640190fd5b600081848411156117bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561178457818101518382015260200161176c565b50505050905090810190601f1680156117b15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50508183035b9392505050565b60008161183a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f42695368617265733a20446976207a65726f0000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a764000083028315806118625750670de0b6b3a764000084828161185f57fe5b04145b6118cd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f42695368617265733a20446976206f766572666c6f7700000000000000000000604482015290519081900360640190fd5b6002830481018181101561194257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f42695368617265733a20446976206f766572666c6f7700000000000000000000604482015290519081900360640190fd5b600084828161194d57fe5b049695505050505050565b600082820283158061197257508284828161196f57fe5b04145b6119dd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f42695368617265733a204d756c206f766572666c6f7700000000000000000000604482015290519081900360640190fd5b6706f05b59d3b20000810181811015611a5757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f42695368617265733a204d756c206f766572666c6f7700000000000000000000604482015290519081900360640190fd5b6000670de0b6b3a76400008261194d565b6000818310611a775781610d15565b5090919050565b33306000805b8451811015610b5d576000858281518110611a9b57fe5b602002602001015190508073ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401611ade919061215b565b60206040518083038186803b158015611af657600080fd5b505afa158015611b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2e9190612143565b92508215611b5757611b5773ffffffffffffffffffffffffffffffffffffffff82168685611b60565b50600101611a84565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610c9c9084906000611c4a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611cc09092919063ffffffff16565b805190915015610c9c57808060200190516020811015611c6957600080fd5b5051610c9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180612364602a913960400191505060405180910390fd5b6060611ccf8484600085611cd7565b949350505050565b606082471015611d32576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806122fa6026913960400191505060405180910390fd5b611d3b85611e91565b611da657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310611e0f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611dd2565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611e71576040519150601f19603f3d011682016040523d82523d6000602084013e611e76565b606091505b5091509150611e86828286611e9b565b979650505050505050565b803b15155b919050565b60608315611eaa5750816117c5565b825115611eba5782518084602001fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181815284516024840152845185939192839260440191908501908083836000831561178457818101518382015260200161176c565b80518015158114611e9657600080fd5b805164ffffffffff81168114611e9657600080fd5b805160ff81168114611e9657600080fd5b80516bffffffffffffffffffffffff81168114611e9657600080fd5b600060208284031215611f7e578081fd5b8135610d15816122d4565b600060208284031215611f9a578081fd5b8151610d15816122d4565b60006020808385031215611fb7578182fd5b825167ffffffffffffffff80821115611fce578384fd5b818501915085601f830112611fe1578384fd5b815181811115611fed57fe5b8381029150611ffd8483016122b0565b8181528481019084860184860187018a1015612017578788fd5b8795505b838610156120455780519450612030856122d4565b8483526001959095019491860191860161201b565b5098975050505050505050565b600060208284031215612063578081fd5b610d1582611f1b565b600060e0828403121561207d578081fd5b60405160e0810181811067ffffffffffffffff8211171561209a57fe5b6040526120a683611f1b565b81526120b460208401611f1b565b60208201526120c560408401611f2b565b60408201526120d660608401611f51565b60608201526120e760808401611f51565b60808201526120f860a08401611f40565b60a082015260c083015160c08201528091505092915050565b600060208284031215612122578081fd5b815171ffffffffffffffffffffffffffffffffffff81168114610d15578182fd5b600060208284031215612154578081fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b73ffffffffffffffffffffffffffffffffffffffff9586168152938516602085015260408401929092529092166060820152608081019190915260a00190565b73ffffffffffffffffffffffffffffffffffffffff94851681529290931660208301526040820152606081019190915260800190565b60208082526018908201527f42695368617265733a2052656365697665642065746865720000000000000000604082015260600190565b90815260200190565b60006040820184835260206040818501528185518084526060860191508287019350845b818110156122a357845183529383019391830191600101612287565b5090979650505050505050565b60405181810167ffffffffffffffff811182821017156122cc57fe5b604052919050565b73ffffffffffffffffffffffffffffffffffffffff811681146122f657600080fd5b5056fe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775472616e7366657248656c7065723a204554485f5452414e534645525f4641494c45445361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220dd7979603dca54fd6da7b647916a7c121fc605cbf712c4206ceeca9a617614e764736f6c6343000706003300000000000000000000000021be370d5312f44cb42ce377bc9b8a0cef1a4c83000000000000000000000000fad492d90e8fcefc080e30284517ca64bd2318ed000000000000000000000000c535f7a7fb3f1e113adec0e2c48d7eb03e892fd3

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000021be370d5312f44cb42ce377bc9b8a0cef1a4c83000000000000000000000000fad492d90e8fcefc080e30284517ca64bd2318ed000000000000000000000000c535f7a7fb3f1e113adec0e2c48d7eb03e892fd3

-----Decoded View---------------
Arg [0] : weth_ (address): 0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83
Arg [1] : oracle_ (address): 0xfad492d90e8fcefc080e30284517ca64bd2318ed
Arg [2] : zapper_ (address): 0xc535f7a7fb3f1e113adec0e2c48d7eb03e892fd3

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000021be370d5312f44cb42ce377bc9b8a0cef1a4c83
Arg [1] : 000000000000000000000000fad492d90e8fcefc080e30284517ca64bd2318ed
Arg [2] : 000000000000000000000000c535f7a7fb3f1e113adec0e2c48d7eb03e892fd3


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Validator ID :
0 FTM

Amount Staked
0

Amount Delegated
0

Staking Total
0

Staking Start Epoch
0

Staking Start Time
0

Proof of Importance
0

Origination Score
0

Validation Score
0

Active
0

Online
0

Downtime
0 s
Address Amount claimed Rewards Created On Epoch Created On
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.