ETH Price: $2,046.34 (+0.49%)

Contract

0x2a49Eae5CCa3f050eBEC729Cf90CC910fADAf7A2
 

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

> 10 Internal Transactions and > 10 Token Transfers found.

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer243948502026-02-06 2:37:4733 days ago1770345467
0x2a49Eae5...0fADAf7A2
16.29898601 ETH
Transfer243948502026-02-06 2:37:4733 days ago1770345467
0x2a49Eae5...0fADAf7A2
16.29898601 ETH
Transfer243563162026-01-31 17:21:3539 days ago1769880095
0x2a49Eae5...0fADAf7A2
2.98453868 ETH
Transfer243563162026-01-31 17:21:3539 days ago1769880095
0x2a49Eae5...0fADAf7A2
2.98453868 ETH
Transfer239964942025-12-12 12:17:5989 days ago1765541879
0x2a49Eae5...0fADAf7A2
1.72607527 ETH
Transfer239964942025-12-12 12:17:5989 days ago1765541879
0x2a49Eae5...0fADAf7A2
1.72607527 ETH
Transfer239880012025-12-11 7:38:3590 days ago1765438715
0x2a49Eae5...0fADAf7A2
4.62991492 ETH
Transfer239880012025-12-11 7:38:3590 days ago1765438715
0x2a49Eae5...0fADAf7A2
4.62991492 ETH
Transfer239105212025-11-30 9:15:59101 days ago1764494159
0x2a49Eae5...0fADAf7A2
17.42345279 ETH
Transfer239105212025-11-30 9:15:59101 days ago1764494159
0x2a49Eae5...0fADAf7A2
17.42345279 ETH
Transfer238919052025-11-27 18:43:59104 days ago1764269039
0x2a49Eae5...0fADAf7A2
0.75792627 ETH
Transfer238919052025-11-27 18:43:59104 days ago1764269039
0x2a49Eae5...0fADAf7A2
0.75792627 ETH
Transfer238531422025-11-22 7:56:11109 days ago1763798171
0x2a49Eae5...0fADAf7A2
57.24169796 ETH
Transfer238531422025-11-22 7:56:11109 days ago1763798171
0x2a49Eae5...0fADAf7A2
57.24169796 ETH
Transfer238394302025-11-20 9:42:47111 days ago1763631767
0x2a49Eae5...0fADAf7A2
68.67839509 ETH
Transfer238394302025-11-20 9:42:47111 days ago1763631767
0x2a49Eae5...0fADAf7A2
68.67839509 ETH
Transfer238348292025-11-19 18:13:23112 days ago1763576003
0x2a49Eae5...0fADAf7A2
37.97562388 ETH
Transfer238348292025-11-19 18:13:23112 days ago1763576003
0x2a49Eae5...0fADAf7A2
37.97562388 ETH
Transfer237471222025-11-07 11:34:23124 days ago1762515263
0x2a49Eae5...0fADAf7A2
224.32800953 ETH
Transfer237471222025-11-07 11:34:23124 days ago1762515263
0x2a49Eae5...0fADAf7A2
224.32800953 ETH
Transfer237250052025-11-04 9:16:11127 days ago1762247771
0x2a49Eae5...0fADAf7A2
116.67362036 ETH
Transfer237250052025-11-04 9:16:11127 days ago1762247771
0x2a49Eae5...0fADAf7A2
116.67362036 ETH
Transfer236279022025-10-21 19:05:47141 days ago1761073547
0x2a49Eae5...0fADAf7A2
9.02738456 ETH
Transfer236279022025-10-21 19:05:47141 days ago1761073547
0x2a49Eae5...0fADAf7A2
9.02738456 ETH
Transfer235498572025-10-10 20:57:35152 days ago1760129855
0x2a49Eae5...0fADAf7A2
140.35313197 ETH
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MultiplyProxyActions

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: AGPL-3.0-or-later

/// MultiplyProxyActions.sol

// Copyright (C) 2021-2021 Oazo Apps Limited

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

import {IERC20} from "../interfaces/IERC20.sol";
import "../utils/SafeMath.sol";
import "../interfaces/IWETH.sol";
import "../interfaces/mcd/IJoin.sol";
import "../interfaces/mcd/IManager.sol";
import "../interfaces/mcd/IVat.sol";
import "../interfaces/mcd/IJug.sol";
import "../interfaces/mcd/IDaiJoin.sol";
import "../interfaces/exchange/IExchange.sol";
import "./ExchangeData.sol";

import "./../flashMint/interface/IERC3156FlashBorrower.sol";
import "./../flashMint/interface/IERC3156FlashLender.sol";

pragma solidity >=0.7.6;
pragma abicoder v2;

struct CdpData {
  address gemJoin;
  address payable fundsReceiver;
  uint256 cdpId;
  bytes32 ilk;
  uint256 requiredDebt;
  uint256 borrowCollateral;
  uint256 withdrawCollateral;
  uint256 withdrawDai;
  uint256 depositDai;
  uint256 depositCollateral;
  bool skipFL;
  string methodName;
}

struct AddressRegistry {
  address jug;
  address manager;
  address multiplyProxyActions;
  address lender;
  address exchange;
}

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// WARNING: These functions meant to be used as a a library for a DSProxy. Some are unsafe if you call them directly.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

contract MultiplyProxyActions is IERC3156FlashBorrower {
  using SafeMath for uint256;

  uint256 constant RAY = 10**27;

  address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
  address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
  address public constant DAIJOIN = 0x9759A6Ac90977b93B58547b4A71c78317f391A28;

  modifier logMethodName(
    string memory name,
    CdpData memory data,
    address destination
  ) {
    if (bytes(data.methodName).length == 0) {
      data.methodName = name;
    }
    _;
    data.methodName = "";
  }

  function takeAFlashLoan(
    AddressRegistry memory addressRegistry,
    CdpData memory cdpData,
    bytes memory paramsData
  ) internal {
    IManager(addressRegistry.manager).cdpAllow(
      cdpData.cdpId,
      addressRegistry.multiplyProxyActions,
      1
    );

    IERC3156FlashLender(addressRegistry.lender).flashLoan(
      IERC3156FlashBorrower(addressRegistry.multiplyProxyActions),
      DAI,
      cdpData.requiredDebt,
      paramsData
    );

    IManager(addressRegistry.manager).cdpAllow(
      cdpData.cdpId,
      addressRegistry.multiplyProxyActions,
      0
    );
  }

  function toInt256(uint256 x) internal pure returns (int256 y) {
    y = int256(x);
    require(y >= 0, "int256-overflow");
  }

  function convertTo18(address gemJoin, uint256 amt) internal returns (uint256 wad) {
    // For those collaterals that have less than 18 decimals precision we need to do the conversion before passing to frob function
    // Adapters will automatically handle the difference of precision
    wad = amt.mul(10**(18 - IJoin(gemJoin).dec()));
  }

  function _getDrawDart(
    address vat,
    address jug,
    address urn,
    bytes32 ilk,
    uint256 wad
  ) internal returns (int256 dart) {
    // Updates stability fee rate
    uint256 rate = IJug(jug).drip(ilk);

    // Gets DAI balance of the urn in the vat
    uint256 dai = IVat(vat).dai(urn);

    // If there was already enough DAI in the vat balance, just exits it without adding more debt
    if (dai < wad.mul(RAY)) {
      // Calculates the needed dart so together with the existing dai in the vat is enough to exit wad amount of DAI tokens
      dart = toInt256(wad.mul(RAY).sub(dai) / rate);
      // This is neeeded due lack of precision. It might need to sum an extra dart wei (for the given DAI wad amount)
      dart = uint256(dart).mul(rate) < wad.mul(RAY) ? dart + 1 : dart;
    }
  }

  function openMultiplyVault(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry
  )
    public
    payable
    logMethodName("openMultiplyVault", cdpData, addressRegistry.multiplyProxyActions)
  {
    cdpData.ilk = IJoin(cdpData.gemJoin).ilk();
    cdpData.cdpId = IManager(addressRegistry.manager).open(cdpData.ilk, address(this));
    increaseMultipleDepositCollateral(exchangeData, cdpData, addressRegistry);
  }

  function increaseMultipleDepositCollateral(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry
  )
    public
    payable
    logMethodName(
      "increaseMultipleDepositCollateral",
      cdpData,
      addressRegistry.multiplyProxyActions
    )
  {
    IGem gem = IJoin(cdpData.gemJoin).gem();

    if (address(gem) == WETH) {
      gem.deposit{value: msg.value}();
      if (cdpData.skipFL == false) {
        gem.transfer(addressRegistry.multiplyProxyActions, msg.value);
      }
    } else {
      if (cdpData.skipFL == false) {
        gem.transferFrom(
          msg.sender,
          addressRegistry.multiplyProxyActions,
          cdpData.depositCollateral
        );
      } else {
        gem.transferFrom(msg.sender, address(this), cdpData.depositCollateral);
      }
    }
    increaseMultipleInternal(exchangeData, cdpData, addressRegistry);
  }

  function toRad(uint256 wad) internal pure returns (uint256 rad) {
    rad = wad.mul(10**27);
  }

  function drawDaiDebt(
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry,
    uint256 amount
  ) internal {
    address urn = IManager(addressRegistry.manager).urns(cdpData.cdpId);
    address vat = IManager(addressRegistry.manager).vat();
    IManager(addressRegistry.manager).frob(
      cdpData.cdpId,
      0,
      _getDrawDart(vat, addressRegistry.jug, urn, cdpData.ilk, amount)
    );
    IManager(addressRegistry.manager).move(cdpData.cdpId, address(this), toRad(amount));
    if (IVat(vat).can(address(this), address(DAIJOIN)) == 0) {
      IVat(vat).hope(DAIJOIN);
    }

    IJoin(DAIJOIN).exit(address(this), amount);
  }

  function increaseMultipleDepositDai(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry
  )
    public
    logMethodName("increaseMultipleDepositDai", cdpData, addressRegistry.multiplyProxyActions)
  {
    if (cdpData.skipFL) {
      IERC20(DAI).transferFrom(msg.sender, address(this), cdpData.depositDai);
    } else {
      IERC20(DAI).transferFrom(
        msg.sender,
        addressRegistry.multiplyProxyActions,
        cdpData.depositDai
      );
    }
    increaseMultipleInternal(exchangeData, cdpData, addressRegistry);
  }

  function increaseMultiple(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry
  ) public logMethodName("increaseMultiple", cdpData, addressRegistry.multiplyProxyActions) {
    increaseMultipleInternal(exchangeData, cdpData, addressRegistry);
  }

  function increaseMultipleInternal(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry
  ) internal {
    cdpData.ilk = IJoin(cdpData.gemJoin).ilk();

    bytes memory paramsData = abi.encode(1, exchangeData, cdpData, addressRegistry);

    if (cdpData.skipFL) {
      //we want to draw our own DAI and use them in the exchange to buy collateral
      IGem gem = IJoin(cdpData.gemJoin).gem();
      uint256 collBalance = IERC20(address(gem)).balanceOf(address(this));
      if (collBalance > 0) {
        //if someone provided some collateral during increase
        //add it to vault and draw DAI
        joinDrawDebt(cdpData, cdpData.requiredDebt, addressRegistry.manager, addressRegistry.jug);
      } else {
        //just draw DAI
        drawDaiDebt(cdpData, addressRegistry, cdpData.requiredDebt);
      }
      _increaseMP(exchangeData, cdpData, addressRegistry, 0);
    } else {
      takeAFlashLoan(addressRegistry, cdpData, paramsData);
    }
  }

  function decreaseMultiple(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry
  ) public logMethodName("decreaseMultiple", cdpData, addressRegistry.multiplyProxyActions) {
    decreaseMultipleInternal(exchangeData, cdpData, addressRegistry);
  }

  function decreaseMultipleInternal(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry
  ) internal {
    cdpData.ilk = IJoin(cdpData.gemJoin).ilk();

    bytes memory paramsData = abi.encode(0, exchangeData, cdpData, addressRegistry);

    if (cdpData.skipFL) {
      _decreaseMP(exchangeData, cdpData, addressRegistry, 0);
    } else {
      takeAFlashLoan(addressRegistry, cdpData, paramsData);
    }
  }

  function decreaseMultipleWithdrawCollateral(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry
  )
    public
    logMethodName(
      "decreaseMultipleWithdrawCollateral",
      cdpData,
      addressRegistry.multiplyProxyActions
    )
  {
    decreaseMultipleInternal(exchangeData, cdpData, addressRegistry);
  }

  function decreaseMultipleWithdrawDai(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry
  )
    public
    logMethodName("decreaseMultipleWithdrawDai", cdpData, addressRegistry.multiplyProxyActions)
  {
    decreaseMultipleInternal(exchangeData, cdpData, addressRegistry);
  }

  function closeVaultExitGeneric(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry,
    uint8 mode
  ) private {
    cdpData.ilk = IJoin(cdpData.gemJoin).ilk();

    address urn = IManager(addressRegistry.manager).urns(cdpData.cdpId);
    address vat = IManager(addressRegistry.manager).vat();

    uint256 wadD = _getWipeAllWad(vat, urn, urn, cdpData.ilk);
    cdpData.requiredDebt = wadD;

    bytes memory paramsData = abi.encode(mode, exchangeData, cdpData, addressRegistry);

    if (cdpData.skipFL == false) {
      takeAFlashLoan(addressRegistry, cdpData, paramsData);
    } else {
      if (mode == 2) {
        _closeWithdrawCollateralSkipFL(
          exchangeData,
          cdpData,
          addressRegistry,
          cdpData.borrowCollateral
        );
      } else {
        require(false, "this code should be unreachable");
      }
    }
  }

  function closeVaultExitCollateral(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry
  )
    public
    logMethodName("closeVaultExitCollateral", cdpData, addressRegistry.multiplyProxyActions)
  {
    closeVaultExitGeneric(exchangeData, cdpData, addressRegistry, 2);
  }

  function closeVaultExitDai(
    ExchangeData calldata exchangeData,
    CdpData memory cdpData,
    AddressRegistry calldata addressRegistry
  ) public logMethodName("closeVaultExitDai", cdpData, addressRegistry.multiplyProxyActions) {
    require(cdpData.skipFL == false, "cannot close to DAI if FL not used");
    closeVaultExitGeneric(exchangeData, cdpData, addressRegistry, 3);
  }

  function joinDrawDebt(
    CdpData memory cdpData,
    uint256 borrowedDai,
    address manager,
    address jug
  ) private {
    IGem gem = IJoin(cdpData.gemJoin).gem();

    uint256 balance = IERC20(address(gem)).balanceOf(address(this));
    gem.approve(address(cdpData.gemJoin), balance);

    address urn = IManager(manager).urns(cdpData.cdpId);
    address vat = IManager(manager).vat();

    IJoin(cdpData.gemJoin).join(urn, balance);

    IManager(manager).frob(
      cdpData.cdpId,
      toInt256(convertTo18(cdpData.gemJoin, balance)),
      _getDrawDart(vat, jug, urn, cdpData.ilk, borrowedDai)
    );
    IManager(manager).move(cdpData.cdpId, address(this), borrowedDai.mul(RAY));

    IVat(vat).hope(DAIJOIN);

    IJoin(DAIJOIN).exit(address(this), borrowedDai);
  }

  function getInk(address manager, CdpData memory cdpData) internal view returns (uint256) {
    address urn = IManager(manager).urns(cdpData.cdpId);
    address vat = IManager(manager).vat();

    (uint256 ink, ) = IVat(vat).urns(cdpData.ilk, urn);
    return ink;
  }

  function _getWipeDart(
    address vat,
    uint256 dai,
    address urn,
    bytes32 ilk
  ) internal view returns (int256 dart) {
    // Gets actual rate from the vat
    (, uint256 rate, , , ) = IVat(vat).ilks(ilk);
    // Gets actual art value of the urn
    (, uint256 art) = IVat(vat).urns(ilk, urn);

    // Uses the whole dai balance in the vat to reduce the debt
    dart = toInt256(dai / rate);
    // Checks the calculated dart is not higher than urn.art (total debt), otherwise uses its value
    dart = uint256(dart) <= art ? -dart : -toInt256(art);
  }

  function _getWipeAllWad(
    address vat,
    address usr,
    address urn,
    bytes32 ilk
  ) internal view returns (uint256 wad) {
    // Gets actual rate from the vat
    (, uint256 rate, , , ) = IVat(vat).ilks(ilk);
    // Gets actual art value of the urn
    (, uint256 art) = IVat(vat).urns(ilk, urn);
    // Gets actual dai amount in the urn
    uint256 dai = IVat(vat).dai(usr);

    uint256 rad = art.mul(rate).sub(dai);
    wad = rad / RAY;

    // If the rad precision has some dust, it will need to request for 1 extra wad wei
    wad = wad.mul(RAY) < rad ? wad + 1 : wad;
  }

  function wipeAndFreeGem(
    address manager,
    address gemJoin,
    uint256 cdp,
    uint256 borrowedDai,
    uint256 collateralDraw
  ) internal {
    address vat = IManager(manager).vat();
    address urn = IManager(manager).urns(cdp);
    bytes32 ilk = IManager(manager).ilks(cdp);

    IERC20(DAI).approve(DAIJOIN, borrowedDai);
    IDaiJoin(DAIJOIN).join(urn, borrowedDai);

    uint256 wadC = convertTo18(gemJoin, collateralDraw);

    IManager(manager).frob(cdp, -toInt256(wadC), _getWipeDart(vat, IVat(vat).dai(urn), urn, ilk));

    IManager(manager).flux(cdp, address(this), wadC);
    IJoin(gemJoin).exit(address(this), collateralDraw);
  }

  function _withdrawGem(
    address gemJoin,
    address payable destination,
    uint256 amount
  ) private {
    IGem gem = IJoin(gemJoin).gem();

    if (address(gem) == WETH) {
      gem.withdraw(amount);
      destination.transfer(amount);
    } else {
      IERC20(address(gem)).transfer(destination, amount);
    }
  }

  function _increaseMP(
    ExchangeData memory exchangeData,
    CdpData memory cdpData,
    AddressRegistry memory addressRegistry,
    uint256 premium
  ) private {
    IExchange exchange = IExchange(addressRegistry.exchange);
    uint256 borrowedDai = cdpData.requiredDebt.add(premium);
    if (cdpData.skipFL) {
      borrowedDai = 0; //this DAI are not borrowed and shal not stay after this method execution
    }
    require(
      IERC20(DAI).approve(address(exchange), exchangeData.fromTokenAmount.add(cdpData.depositDai)),
      "MPA / Could not approve Exchange for DAI"
    );
    exchange.swapDaiForToken(
      exchangeData.toTokenAddress,
      exchangeData.fromTokenAmount.add(cdpData.depositDai),
      exchangeData.minToTokenAmount,
      exchangeData.exchangeAddress,
      exchangeData._exchangeCalldata
    );
    //here we add collateral we got from exchange, if skipFL then borrowedDai = 0
    joinDrawDebt(cdpData, borrowedDai, addressRegistry.manager, addressRegistry.jug);
    //if some DAI are left after exchange return them to the user
    uint256 daiLeft = IERC20(DAI).balanceOf(address(this)).sub(borrowedDai);
    emit MultipleActionCalled(
      cdpData.methodName,
      cdpData.cdpId,
      exchangeData.minToTokenAmount,
      exchangeData.toTokenAmount,
      0,
      daiLeft
    );

    if (daiLeft > 0) {
      IERC20(DAI).transfer(cdpData.fundsReceiver, daiLeft);
    }
  }

  function _decreaseMP(
    ExchangeData memory exchangeData,
    CdpData memory cdpData,
    AddressRegistry memory addressRegistry,
    uint256 premium
  ) private {
    IExchange exchange = IExchange(addressRegistry.exchange);

    uint256 debtToBeWiped = cdpData.skipFL ? 0 : cdpData.requiredDebt.sub(cdpData.withdrawDai);

    wipeAndFreeGem(
      addressRegistry.manager,
      cdpData.gemJoin,
      cdpData.cdpId,
      debtToBeWiped,
      cdpData.borrowCollateral.add(cdpData.withdrawCollateral)
    );

    require(
      IERC20(exchangeData.fromTokenAddress).approve(
        address(exchange),
        exchangeData.fromTokenAmount
      ),
      "MPA / Could not approve Exchange for Token"
    );

    exchange.swapTokenForDai(
      exchangeData.fromTokenAddress,
      exchangeData.fromTokenAmount,
      cdpData.requiredDebt.add(premium),
      exchangeData.exchangeAddress,
      exchangeData._exchangeCalldata
    );

    uint256 collateralLeft = IERC20(exchangeData.fromTokenAddress).balanceOf(address(this));

    uint256 daiLeft = 0;
    if (cdpData.skipFL) {
      wipeAndFreeGem(
        addressRegistry.manager,
        cdpData.gemJoin,
        cdpData.cdpId,
        IERC20(DAI).balanceOf(address(this)).sub(cdpData.withdrawDai),
        0
      );
      daiLeft = cdpData.withdrawDai;
    } else {
      daiLeft = IERC20(DAI).balanceOf(address(this)).sub(cdpData.requiredDebt.add(premium));
    }
    emit MultipleActionCalled(
      cdpData.methodName,
      cdpData.cdpId,
      exchangeData.minToTokenAmount,
      exchangeData.toTokenAmount,
      collateralLeft,
      daiLeft
    );

    if (daiLeft > 0) {
      IERC20(DAI).transfer(cdpData.fundsReceiver, daiLeft);
    }
    if (collateralLeft > 0) {
      _withdrawGem(cdpData.gemJoin, cdpData.fundsReceiver, collateralLeft);
    }
  }

  function _closeWithdrawCollateralSkipFL(
    ExchangeData memory exchangeData,
    CdpData memory cdpData,
    AddressRegistry memory addressRegistry,
    uint256 ink
  ) private {
    IExchange exchange = IExchange(addressRegistry.exchange);
    address gemAddress = address(IJoin(cdpData.gemJoin).gem());

    wipeAndFreeGem(
      addressRegistry.manager,
      cdpData.gemJoin,
      cdpData.cdpId,
      0,
      exchangeData.fromTokenAmount
    );
    require(
      IERC20(exchangeData.fromTokenAddress).approve(address(exchange), ink),
      "MPA / Could not approve Exchange for Token"
    );
    exchange.swapTokenForDai(
      exchangeData.fromTokenAddress,
      exchangeData.fromTokenAmount,
      exchangeData.minToTokenAmount,
      exchangeData.exchangeAddress,
      exchangeData._exchangeCalldata
    );

    uint256 daiLeft = IERC20(DAI).balanceOf(address(this));

    require(cdpData.requiredDebt <= daiLeft, "cannot repay all debt");
    
    wipeAndFreeGem(
      addressRegistry.manager,
      cdpData.gemJoin,
      cdpData.cdpId,
      cdpData.requiredDebt,
      cdpData.withdrawCollateral
    );
    daiLeft = IERC20(DAI).balanceOf(address(this));

    uint256 collateralLeft = IERC20(gemAddress).balanceOf(address(this));

    if (daiLeft > 0) {
      IERC20(DAI).transfer(cdpData.fundsReceiver, daiLeft);
    }
    if (collateralLeft > 0) {
      _withdrawGem(cdpData.gemJoin, cdpData.fundsReceiver, collateralLeft);
    }
    emit MultipleActionCalled(
      cdpData.methodName,
      cdpData.cdpId,
      exchangeData.minToTokenAmount,
      exchangeData.toTokenAmount,
      collateralLeft,
      daiLeft
    );
  }

  function _closeWithdrawCollateral(
    ExchangeData memory exchangeData,
    CdpData memory cdpData,
    AddressRegistry memory addressRegistry,
    uint256 borrowedDaiAmount,
    uint256 ink
  ) private {
    IExchange exchange = IExchange(addressRegistry.exchange);
    address gemAddress = address(IJoin(cdpData.gemJoin).gem());

    wipeAndFreeGem(
      addressRegistry.manager,
      cdpData.gemJoin,
      cdpData.cdpId,
      cdpData.requiredDebt,
      ink
    );

    require(
      IERC20(exchangeData.fromTokenAddress).approve(address(exchange), ink),
      "MPA / Could not approve Exchange for Token"
    );
    exchange.swapTokenForDai(
      exchangeData.fromTokenAddress,
      exchangeData.fromTokenAmount,
      exchangeData.minToTokenAmount,
      exchangeData.exchangeAddress,
      exchangeData._exchangeCalldata
    );

    uint256 daiLeft = IERC20(DAI).balanceOf(address(this)).sub(borrowedDaiAmount);
    uint256 collateralLeft = IERC20(gemAddress).balanceOf(address(this));

    if (daiLeft > 0) {
      IERC20(DAI).transfer(cdpData.fundsReceiver, daiLeft);
    }
    if (collateralLeft > 0) {
      _withdrawGem(cdpData.gemJoin, cdpData.fundsReceiver, collateralLeft);
    }
    emit MultipleActionCalled(
      cdpData.methodName,
      cdpData.cdpId,
      exchangeData.minToTokenAmount,
      exchangeData.toTokenAmount,
      collateralLeft,
      daiLeft
    );
  }

  function _closeWithdrawDai(
    ExchangeData memory exchangeData,
    CdpData memory cdpData,
    AddressRegistry memory addressRegistry,
    uint256 borrowedDaiAmount,
    uint256 ink
  ) private {
    IExchange exchange = IExchange(addressRegistry.exchange);
    address gemAddress = address(IJoin(cdpData.gemJoin).gem());

    wipeAndFreeGem(
      addressRegistry.manager,
      cdpData.gemJoin,
      cdpData.cdpId,
      cdpData.requiredDebt,
      ink
    );

    require(
      IERC20(exchangeData.fromTokenAddress).approve(
        address(exchange),
        IERC20(gemAddress).balanceOf(address(this))
      ),
      "MPA / Could not approve Exchange for Token"
    );
    exchange.swapTokenForDai(
      exchangeData.fromTokenAddress,
      ink,
      exchangeData.minToTokenAmount,
      exchangeData.exchangeAddress,
      exchangeData._exchangeCalldata
    );

    uint256 daiLeft = IERC20(DAI).balanceOf(address(this)).sub(borrowedDaiAmount);

    if (daiLeft > 0) {
      IERC20(DAI).transfer(cdpData.fundsReceiver, daiLeft);
    }
    uint256 collateralLeft = IERC20(gemAddress).balanceOf(address(this));
    /*
    if (collateralLeft > 0) {
      _withdrawGem(cdpData.gemJoin, cdpData.fundsReceiver, collateralLeft);
    }*/
    emit MultipleActionCalled(
      cdpData.methodName,
      cdpData.cdpId,
      exchangeData.minToTokenAmount,
      exchangeData.toTokenAmount,
      collateralLeft,
      daiLeft
    );
  }

  function onFlashLoan(
    address initiator,
    address token,
    uint256 amount,
    uint256 fee,
    bytes calldata params
  ) public override returns (bytes32) {
    (
      uint8 mode,
      ExchangeData memory exchangeData,
      CdpData memory cdpData,
      AddressRegistry memory addressRegistry
    ) = abi.decode(params, (uint8, ExchangeData, CdpData, AddressRegistry));

    require(msg.sender == address(addressRegistry.lender), "mpa-untrusted-lender");

    uint256 borrowedDaiAmount = amount.add(fee);
    emit FLData(IERC20(DAI).balanceOf(address(this)).sub(cdpData.depositDai), borrowedDaiAmount);

    require(
      cdpData.requiredDebt.add(cdpData.depositDai) <= IERC20(DAI).balanceOf(address(this)),
      "mpa-receive-requested-amount-mismatch"
    );

    if (mode == 0) {
      _decreaseMP(exchangeData, cdpData, addressRegistry, fee);
    }
    if (mode == 1) {
      _increaseMP(exchangeData, cdpData, addressRegistry, fee);
    }
    if (mode == 2) {
      _closeWithdrawCollateral(
        exchangeData,
        cdpData,
        addressRegistry,
        borrowedDaiAmount,
        cdpData.borrowCollateral
      );
    }
    if (mode == 3) {
      _closeWithdrawDai(
        exchangeData,
        cdpData,
        addressRegistry,
        borrowedDaiAmount,
        cdpData.borrowCollateral
      );
    }

    IERC20(token).approve(addressRegistry.lender, borrowedDaiAmount);

    return keccak256("ERC3156FlashBorrower.onFlashLoan");
  }

  event FLData(uint256 borrowed, uint256 due);
  event MultipleActionCalled(
    string methodName,
    uint256 indexed cdpId,
    uint256 swapMinAmount,
    uint256 swapOptimistAmount,
    uint256 collateralLeft,
    uint256 daiLeft
  );

  fallback() external payable {}
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

interface IERC20 {
  function totalSupply() external view returns (uint256 supply);

  function balanceOf(address _owner) external view returns (uint256 balance);

  function transfer(address _to, uint256 _value) external returns (bool success);

  function transferFrom(
    address _from,
    address _to,
    uint256 _value
  ) external returns (bool success);

  function approve(address _spender, uint256 _value) external returns (bool success);

  function allowance(address _owner, address _spender) external view returns (uint256 remaining);

  function decimals() external view returns (uint256 digits);

  event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

// SPDX-License-Identifier: MIT

pragma solidity >=0.7.6;

library SafeMath {
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a, 'SafeMath: addition overflow');

    return c;
  }

  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    return sub(a, b, 'SafeMath: subtraction overflow');
  }

  function sub(
    uint256 a,
    uint256 b,
    string memory errorMessage
  ) internal pure returns (uint256) {
    require(b <= a, errorMessage);
    uint256 c = a - b;

    return c;
  }

  function mul(uint256 a, uint256 b) internal pure returns (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 0;
    }

    uint256 c = a * b;
    require(c / a == b, 'SafeMath: multiplication overflow');

    return c;
  }

  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    return div(a, b, 'SafeMath: division by zero');
  }

  function div(
    uint256 a,
    uint256 b,
    string memory errorMessage
  ) internal pure returns (uint256) {
    require(b > 0, errorMessage);
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }

  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    return mod(a, b, 'SafeMath: modulo by zero');
  }

  function mod(
    uint256 a,
    uint256 b,
    string memory errorMessage
  ) internal pure returns (uint256) {
    require(b != 0, errorMessage);
    return a % b;
  }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

import './IERC20.sol';

abstract contract IWETH {
  function allowance(address, address) public virtual returns (uint256);

  function balanceOf(address) public virtual returns (uint256);

  function approve(address, uint256) public virtual;

  function transfer(address, uint256) public virtual returns (bool);

  function transferFrom(
    address,
    address,
    uint256
  ) public virtual returns (bool);

  function deposit() public payable virtual;

  function withdraw(uint256) public virtual;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

import './IGem.sol';

abstract contract IJoin {
  bytes32 public ilk;

  function dec() public view virtual returns (uint256);

  function gem() public view virtual returns (IGem);

  function join(address, uint256) public payable virtual;

  function exit(address, uint256) public virtual;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

abstract contract IManager {
  function last(address) public virtual returns (uint256);

  function cdpCan(
    address,
    uint256,
    address
  ) public view virtual returns (uint256);

  function ilks(uint256) public view virtual returns (bytes32);

  function owns(uint256) public view virtual returns (address);

  function urns(uint256) public view virtual returns (address);

  function vat() public view virtual returns (address);

  function open(bytes32, address) public virtual returns (uint256);

  function give(uint256, address) public virtual;

  function cdpAllow(
    uint256,
    address,
    uint256
  ) public virtual;

  function urnAllow(address, uint256) public virtual;

  function frob(
    uint256,
    int256,
    int256
  ) public virtual;

  function flux(
    uint256,
    address,
    uint256
  ) public virtual;

  function move(
    uint256,
    address,
    uint256
  ) public virtual;

  function exit(
    address,
    uint256,
    address,
    uint256
  ) public virtual;

  function quit(uint256, address) public virtual;

  function enter(address, uint256) public virtual;

  function shift(uint256, uint256) public virtual;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

abstract contract IVat {
  struct Urn {
    uint256 ink; // Locked Collateral  [wad]
    uint256 art; // Normalised Debt    [wad]
  }

  struct Ilk {
    uint256 Art; // Total Normalised Debt     [wad]
    uint256 rate; // Accumulated Rates         [ray]
    uint256 spot; // Price with Safety Margin  [ray]
    uint256 line; // Debt Ceiling              [rad]
    uint256 dust; // Urn Debt Floor            [rad]
  }

  mapping(bytes32 => mapping(address => Urn)) public urns;
  mapping(bytes32 => Ilk) public ilks;
  mapping(bytes32 => mapping(address => uint256)) public gem; // [wad]

  function can(address, address) public view virtual returns (uint256);

  function dai(address) public view virtual returns (uint256);

  function frob(
    bytes32,
    address,
    address,
    address,
    int256,
    int256
  ) public virtual;

  function hope(address) public virtual;

  function move(
    address,
    address,
    uint256
  ) public virtual;

  function fork(
    bytes32,
    address,
    address,
    int256,
    int256
  ) public virtual;
}

File 8 of 14 : IJug.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

abstract contract IJug {
  struct Ilk {
    uint256 duty;
    uint256 rho;
  }

  mapping(bytes32 => Ilk) public ilks;

  function drip(bytes32) public virtual returns (uint256);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

import './IVat.sol';
import './IGem.sol';

abstract contract IDaiJoin {
  function vat() public virtual returns (IVat);

  function dai() public virtual returns (IGem);

  function join(address, uint256) public payable virtual;

  function exit(address, uint256) public virtual;
}

pragma solidity >=0.7.0;

abstract contract IExchange {
  function swapDaiForToken(
    address asset,
    uint256 amount,
    uint256 receiveAtLeast,
    address callee,
    bytes calldata withData
  ) external virtual;

  function swapTokenForDai(
    address asset,
    uint256 amount,
    uint256 receiveAtLeast,
    address callee,
    bytes calldata withData
  ) external virtual;
}

File 11 of 14 : ExchangeData.sol
// SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity >=0.7.6;

struct ExchangeData {
  address fromTokenAddress;
  address toTokenAddress;
  uint256 fromTokenAmount;
  uint256 toTokenAmount;
  uint256 minToTokenAmount;
  address exchangeAddress;
  bytes _exchangeCalldata;
}

File 12 of 14 : IERC3156FlashBorrower.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2021 Dai Foundation
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

pragma solidity >=0.6.12;

interface IERC3156FlashBorrower {

    /**
     * @dev Receive a flash loan.
     * @param initiator The initiator of the loan.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @param fee The additional amount of tokens to repay.
     * @param data Arbitrary data structure, intended to contain user-defined parameters.
     * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan"
     */
    function onFlashLoan(
        address initiator,
        address token,
        uint256 amount,
        uint256 fee,
        bytes calldata data
    ) external returns (bytes32);
}

// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2021 Dai Foundation
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

pragma solidity >=0.6.12;

import "./IERC3156FlashBorrower.sol";

interface IERC3156FlashLender {

    /**
     * @dev The amount of currency available to be lent.
     * @param token The loan currency.
     * @return The amount of `token` that can be borrowed.
     */
    function maxFlashLoan(
        address token
    ) external view returns (uint256);

    /**
     * @dev The fee to be charged for a given loan.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @return The amount of `token` to be charged for the loan, on top of the returned principal.
     */
    function flashFee(
        address token,
        uint256 amount
    ) external view returns (uint256);

    /**
     * @dev Initiate a flash loan.
     * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @param data Arbitrary data structure, intended to contain user-defined parameters.
     */
    function flashLoan(
        IERC3156FlashBorrower receiver,
        address token,
        uint256 amount,
        bytes calldata data
    ) external returns (bool);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

abstract contract IGem {
  function dec() public virtual returns (uint256);

  function gem() public virtual returns (IGem);

  function join(address, uint256) public payable virtual;

  function exit(address, uint256) public virtual;

  function approve(address, uint256) public virtual;

  function transfer(address, uint256) public virtual returns (bool);

  function transferFrom(
    address,
    address,
    uint256
  ) public virtual returns (bool);

  function deposit() public payable virtual;

  function withdraw(uint256) public virtual;

  function allowance(address, address) public virtual returns (uint256);
}

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

Contract Security Audit

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"borrowed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"due","type":"uint256"}],"name":"FLData","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"methodName","type":"string"},{"indexed":true,"internalType":"uint256","name":"cdpId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"swapMinAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"swapOptimistAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralLeft","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"daiLeft","type":"uint256"}],"name":"MultipleActionCalled","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"DAI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAIJOIN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"fromTokenAddress","type":"address"},{"internalType":"address","name":"toTokenAddress","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"toTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minToTokenAmount","type":"uint256"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"bytes","name":"_exchangeCalldata","type":"bytes"}],"internalType":"struct ExchangeData","name":"exchangeData","type":"tuple"},{"components":[{"internalType":"address","name":"gemJoin","type":"address"},{"internalType":"address payable","name":"fundsReceiver","type":"address"},{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"uint256","name":"requiredDebt","type":"uint256"},{"internalType":"uint256","name":"borrowCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawDai","type":"uint256"},{"internalType":"uint256","name":"depositDai","type":"uint256"},{"internalType":"uint256","name":"depositCollateral","type":"uint256"},{"internalType":"bool","name":"skipFL","type":"bool"},{"internalType":"string","name":"methodName","type":"string"}],"internalType":"struct CdpData","name":"cdpData","type":"tuple"},{"components":[{"internalType":"address","name":"jug","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"address","name":"multiplyProxyActions","type":"address"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"closeVaultExitCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"fromTokenAddress","type":"address"},{"internalType":"address","name":"toTokenAddress","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"toTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minToTokenAmount","type":"uint256"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"bytes","name":"_exchangeCalldata","type":"bytes"}],"internalType":"struct ExchangeData","name":"exchangeData","type":"tuple"},{"components":[{"internalType":"address","name":"gemJoin","type":"address"},{"internalType":"address payable","name":"fundsReceiver","type":"address"},{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"uint256","name":"requiredDebt","type":"uint256"},{"internalType":"uint256","name":"borrowCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawDai","type":"uint256"},{"internalType":"uint256","name":"depositDai","type":"uint256"},{"internalType":"uint256","name":"depositCollateral","type":"uint256"},{"internalType":"bool","name":"skipFL","type":"bool"},{"internalType":"string","name":"methodName","type":"string"}],"internalType":"struct CdpData","name":"cdpData","type":"tuple"},{"components":[{"internalType":"address","name":"jug","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"address","name":"multiplyProxyActions","type":"address"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"closeVaultExitDai","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"fromTokenAddress","type":"address"},{"internalType":"address","name":"toTokenAddress","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"toTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minToTokenAmount","type":"uint256"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"bytes","name":"_exchangeCalldata","type":"bytes"}],"internalType":"struct ExchangeData","name":"exchangeData","type":"tuple"},{"components":[{"internalType":"address","name":"gemJoin","type":"address"},{"internalType":"address payable","name":"fundsReceiver","type":"address"},{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"uint256","name":"requiredDebt","type":"uint256"},{"internalType":"uint256","name":"borrowCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawDai","type":"uint256"},{"internalType":"uint256","name":"depositDai","type":"uint256"},{"internalType":"uint256","name":"depositCollateral","type":"uint256"},{"internalType":"bool","name":"skipFL","type":"bool"},{"internalType":"string","name":"methodName","type":"string"}],"internalType":"struct CdpData","name":"cdpData","type":"tuple"},{"components":[{"internalType":"address","name":"jug","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"address","name":"multiplyProxyActions","type":"address"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"decreaseMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"fromTokenAddress","type":"address"},{"internalType":"address","name":"toTokenAddress","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"toTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minToTokenAmount","type":"uint256"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"bytes","name":"_exchangeCalldata","type":"bytes"}],"internalType":"struct ExchangeData","name":"exchangeData","type":"tuple"},{"components":[{"internalType":"address","name":"gemJoin","type":"address"},{"internalType":"address payable","name":"fundsReceiver","type":"address"},{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"uint256","name":"requiredDebt","type":"uint256"},{"internalType":"uint256","name":"borrowCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawDai","type":"uint256"},{"internalType":"uint256","name":"depositDai","type":"uint256"},{"internalType":"uint256","name":"depositCollateral","type":"uint256"},{"internalType":"bool","name":"skipFL","type":"bool"},{"internalType":"string","name":"methodName","type":"string"}],"internalType":"struct CdpData","name":"cdpData","type":"tuple"},{"components":[{"internalType":"address","name":"jug","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"address","name":"multiplyProxyActions","type":"address"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"decreaseMultipleWithdrawCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"fromTokenAddress","type":"address"},{"internalType":"address","name":"toTokenAddress","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"toTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minToTokenAmount","type":"uint256"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"bytes","name":"_exchangeCalldata","type":"bytes"}],"internalType":"struct ExchangeData","name":"exchangeData","type":"tuple"},{"components":[{"internalType":"address","name":"gemJoin","type":"address"},{"internalType":"address payable","name":"fundsReceiver","type":"address"},{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"uint256","name":"requiredDebt","type":"uint256"},{"internalType":"uint256","name":"borrowCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawDai","type":"uint256"},{"internalType":"uint256","name":"depositDai","type":"uint256"},{"internalType":"uint256","name":"depositCollateral","type":"uint256"},{"internalType":"bool","name":"skipFL","type":"bool"},{"internalType":"string","name":"methodName","type":"string"}],"internalType":"struct CdpData","name":"cdpData","type":"tuple"},{"components":[{"internalType":"address","name":"jug","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"address","name":"multiplyProxyActions","type":"address"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"decreaseMultipleWithdrawDai","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"fromTokenAddress","type":"address"},{"internalType":"address","name":"toTokenAddress","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"toTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minToTokenAmount","type":"uint256"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"bytes","name":"_exchangeCalldata","type":"bytes"}],"internalType":"struct ExchangeData","name":"exchangeData","type":"tuple"},{"components":[{"internalType":"address","name":"gemJoin","type":"address"},{"internalType":"address payable","name":"fundsReceiver","type":"address"},{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"uint256","name":"requiredDebt","type":"uint256"},{"internalType":"uint256","name":"borrowCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawDai","type":"uint256"},{"internalType":"uint256","name":"depositDai","type":"uint256"},{"internalType":"uint256","name":"depositCollateral","type":"uint256"},{"internalType":"bool","name":"skipFL","type":"bool"},{"internalType":"string","name":"methodName","type":"string"}],"internalType":"struct CdpData","name":"cdpData","type":"tuple"},{"components":[{"internalType":"address","name":"jug","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"address","name":"multiplyProxyActions","type":"address"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"increaseMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"fromTokenAddress","type":"address"},{"internalType":"address","name":"toTokenAddress","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"toTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minToTokenAmount","type":"uint256"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"bytes","name":"_exchangeCalldata","type":"bytes"}],"internalType":"struct ExchangeData","name":"exchangeData","type":"tuple"},{"components":[{"internalType":"address","name":"gemJoin","type":"address"},{"internalType":"address payable","name":"fundsReceiver","type":"address"},{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"uint256","name":"requiredDebt","type":"uint256"},{"internalType":"uint256","name":"borrowCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawDai","type":"uint256"},{"internalType":"uint256","name":"depositDai","type":"uint256"},{"internalType":"uint256","name":"depositCollateral","type":"uint256"},{"internalType":"bool","name":"skipFL","type":"bool"},{"internalType":"string","name":"methodName","type":"string"}],"internalType":"struct CdpData","name":"cdpData","type":"tuple"},{"components":[{"internalType":"address","name":"jug","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"address","name":"multiplyProxyActions","type":"address"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"increaseMultipleDepositCollateral","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"fromTokenAddress","type":"address"},{"internalType":"address","name":"toTokenAddress","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"toTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minToTokenAmount","type":"uint256"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"bytes","name":"_exchangeCalldata","type":"bytes"}],"internalType":"struct ExchangeData","name":"exchangeData","type":"tuple"},{"components":[{"internalType":"address","name":"gemJoin","type":"address"},{"internalType":"address payable","name":"fundsReceiver","type":"address"},{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"uint256","name":"requiredDebt","type":"uint256"},{"internalType":"uint256","name":"borrowCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawDai","type":"uint256"},{"internalType":"uint256","name":"depositDai","type":"uint256"},{"internalType":"uint256","name":"depositCollateral","type":"uint256"},{"internalType":"bool","name":"skipFL","type":"bool"},{"internalType":"string","name":"methodName","type":"string"}],"internalType":"struct CdpData","name":"cdpData","type":"tuple"},{"components":[{"internalType":"address","name":"jug","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"address","name":"multiplyProxyActions","type":"address"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"increaseMultipleDepositDai","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"initiator","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"onFlashLoan","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"fromTokenAddress","type":"address"},{"internalType":"address","name":"toTokenAddress","type":"address"},{"internalType":"uint256","name":"fromTokenAmount","type":"uint256"},{"internalType":"uint256","name":"toTokenAmount","type":"uint256"},{"internalType":"uint256","name":"minToTokenAmount","type":"uint256"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"bytes","name":"_exchangeCalldata","type":"bytes"}],"internalType":"struct ExchangeData","name":"exchangeData","type":"tuple"},{"components":[{"internalType":"address","name":"gemJoin","type":"address"},{"internalType":"address payable","name":"fundsReceiver","type":"address"},{"internalType":"uint256","name":"cdpId","type":"uint256"},{"internalType":"bytes32","name":"ilk","type":"bytes32"},{"internalType":"uint256","name":"requiredDebt","type":"uint256"},{"internalType":"uint256","name":"borrowCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawCollateral","type":"uint256"},{"internalType":"uint256","name":"withdrawDai","type":"uint256"},{"internalType":"uint256","name":"depositDai","type":"uint256"},{"internalType":"uint256","name":"depositCollateral","type":"uint256"},{"internalType":"bool","name":"skipFL","type":"bool"},{"internalType":"string","name":"methodName","type":"string"}],"internalType":"struct CdpData","name":"cdpData","type":"tuple"},{"components":[{"internalType":"address","name":"jug","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"address","name":"multiplyProxyActions","type":"address"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"openMultiplyVault","outputs":[],"stateMutability":"payable","type":"function"}]

608060405234801561001057600080fd5b506147e8806100206000396000f3fe6080604052600436106100c25760003560e01c80634a9b4e0c1161007f578063ad5c464811610059578063ad5c4648146101ed578063cedee4ef1461020f578063e0bab4c414610222578063f85c2ce314610237576100c2565b80634a9b4e0c1461019a57806371ae86a5146101ba57806399e13c1a146101da576100c2565b80630521a3c7146100c45780631c9ea1e0146100e45780631f41f7b61461010457806323e30c8b1461012457806334f674731461015a5780633b9b4d951461017a575b005b3480156100d057600080fd5b506100c26100df366004613f4c565b61024c565b3480156100f057600080fd5b506100c26100ff366004613f4c565b6102b2565b34801561011057600080fd5b506100c261011f366004613f4c565b6102eb565b34801561013057600080fd5b5061014461013f366004613e58565b610372565b60405161015191906143d4565b60405180910390f35b34801561016657600080fd5b506100c2610175366004613f4c565b61066f565b34801561018657600080fd5b506100c2610195366004613f4c565b6106b5565b3480156101a657600080fd5b506100c26101b5366004613f4c565b61071c565b3480156101c657600080fd5b506100c26101d5366004613f4c565b610774565b6100c26101e8366004613f4c565b610912565b3480156101f957600080fd5b50610202610a7d565b604051610151919061432f565b6100c261021d366004613f4c565b610a95565b34801561022e57600080fd5b50610202610d68565b34801561024357600080fd5b50610202610d7a565b60405180606001604052806022815260200161470f60229139826102766060840160408501613e20565b6101608201515161028a5761016082018390525b610295868686610d92565b506040805160208101909152600081526101609091015250505050565b604080518082018252601081526f64656372656173654d756c7469706c6560801b60208201529083906102769060608501908501613e20565b6040805180820182526011815270636c6f73655661756c744578697444616960781b60208201529083906103259060608501908501613e20565b610160820151516103395761016082018390525b610140850151156103655760405162461bcd60e51b815260040161035c90614516565b60405180910390fd5b6102958686866003610e89565b60008080808061038486880188614031565b935093509350935080606001516001600160a01b0316336001600160a01b0316146103c15760405162461bcd60e51b815260040161035c90614610565b60006103cd8a8a6110df565b90507f9c6641b21946115d10f3f55df9bec5752ec06d40dc9250b1cc6560549764600e6104898461010001516000805160206147518339815191526001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610433919061432f565b60206040518083038186803b15801561044b57600080fd5b505afa15801561045f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104839190613f19565b90611142565b826040516104989291906146aa565b60405180910390a16040516370a0823160e01b8152600080516020614751833981519152906370a08231906104d190309060040161432f565b60206040518083038186803b1580156104e957600080fd5b505afa1580156104fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105219190613f19565b6101008401516080850151610535916110df565b11156105535760405162461bcd60e51b815260040161035c906145cb565b60ff8516610567576105678484848c611184565b8460ff166001141561057f5761057f8484848c611534565b8460ff166002141561059c5761059c848484848760a001516117da565b8460ff16600314156105b9576105b9848484848760a00151611b40565b606082015160405163095ea7b360e01b81526001600160a01b038d169163095ea7b3916105eb91908590600401614381565b602060405180830381600087803b15801561060557600080fd5b505af1158015610619573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063d9190613efd565b507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd99c9b505050505050505050505050565b604080518082018252601b81527f64656372656173654d756c7469706c655769746864726177446169000000000060208201529083906102769060608501908501613e20565b604080518082018252601881527f636c6f73655661756c7445786974436f6c6c61746572616c000000000000000060208201529083906106fb9060608501908501613e20565b6101608201515161070f5761016082018390525b6102958686866002610e89565b604080518082018252601081526f696e6372656173654d756c7469706c6560801b60208201529083906107559060608501908501613e20565b610160820151516107695761016082018390525b610295868686611ef3565b604080518082018252601a81527f696e6372656173654d756c7469706c654465706f73697444616900000000000060208201529083906107ba9060608501908501613e20565b610160820151516107ce5761016082018390525b8461014001511561086b576101008501516040516323b872dd60e01b8152600080516020614751833981519152916323b872dd9161081391339130919060040161435d565b602060405180830381600087803b15801561082d57600080fd5b505af1158015610841573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108659190613efd565b50610769565b6000805160206147518339815191526323b872dd336108906060880160408901613e20565b8861010001516040518463ffffffff1660e01b81526004016108b49392919061435d565b602060405180830381600087803b1580156108ce57600080fd5b505af11580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109069190613efd565b50610295868686611ef3565b60408051808201825260118152701bdc195b935d5b1d1a5c1b1e55985d5b1d607a1b602082015290839061094c9060608501908501613e20565b610160820151516109605761016082018390525b84600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561099d57600080fd5b505afa1580156109b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d59190613f19565b60608601526109ea6040850160208601613e20565b6001600160a01b0316636090dec58660600151306040518363ffffffff1660e01b8152600401610a1b9291906143dd565b602060405180830381600087803b158015610a3557600080fd5b505af1158015610a49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6d9190613f19565b6040860152610295868686610a95565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6040518060600160405280602181526020016147716021913982610abf6060840160408501613e20565b61016082015151610ad35761016082018390525b600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1257600080fd5b505afa158015610b26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4a9190613e3c565b90506001600160a01b03811673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415610c6857806001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610bac57600080fd5b505af1158015610bc0573d6000803e3d6000fd5b5050505061014087015115159050610c63576001600160a01b03811663a9059cbb610bf16060880160408901613e20565b346040518363ffffffff1660e01b8152600401610c0f929190614381565b602060405180830381600087803b158015610c2957600080fd5b505af1158015610c3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c619190613efd565b505b610d3f565b610140860151610cb6576001600160a01b0381166323b872dd33610c926060890160408a01613e20565b8961012001516040518463ffffffff1660e01b8152600401610c0f9392919061435d565b6101208601516040516323b872dd60e01b81526001600160a01b038316916323b872dd91610ceb91339130919060040161435d565b602060405180830381600087803b158015610d0557600080fd5b505af1158015610d19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3d9190613efd565b505b610d4a878787611ef3565b50506040805160208101909152600081526101609091015250505050565b60008051602061475183398151915281565b739759a6ac90977b93b58547b4a71c78317f391a2881565b81600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dcf57600080fd5b505afa158015610de3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e079190613f19565b6060830152604051600090610e26908290869086908690602001614427565b604051602081830303815290604052905082610140015115610e6a57610e65610e4e856146dc565b84610e5e36869003860186613f31565b6000611184565b610e83565b610e83610e7c36849003840184613f31565b848361210e565b50505050565b82600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ec657600080fd5b505afa158015610eda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efe9190613f19565b60608401526000610f156040840160208501613e20565b6001600160a01b0316632726b07385604001516040518263ffffffff1660e01b8152600401610f4491906143d4565b60206040518083038186803b158015610f5c57600080fd5b505afa158015610f70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f949190613e3c565b90506000610fa86040850160208601613e20565b6001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015610fe057600080fd5b505afa158015610ff4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110189190613e3c565b9050600061102c8284858960600151612287565b608087018190526040519091506000906110509086908a908a908a90602001614427565b60408051601f1981840301815291905261014088015190915061108b5761108661107f36889003880188613f31565b888361210e565b6110d5565b8460ff16600214156110bd576110866110a3896146dc565b886110b3368a90038a018a613f31565b8a60a00151612463565b60405162461bcd60e51b815260040161035c9061463e565b5050505050505050565b600082820183811015611139576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600061113983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506128db565b60808201516101408401516000906111ae5760e085015160808601516111a991611142565b6111b1565b60005b90506111e6846020015186600001518760400151846111e18a60c001518b60a001516110df90919063ffffffff16565b612972565b8551604080880151905163095ea7b360e01b81526001600160a01b039092169163095ea7b39161121b91869190600401614381565b602060405180830381600087803b15801561123557600080fd5b505af1158015611249573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126d9190613efd565b6112895760405162461bcd60e51b815260040161035c90614558565b816001600160a01b031663c723c87f876000015188604001516112b9878a608001516110df90919063ffffffff16565b8a60a001518b60c001516040518663ffffffff1660e01b81526004016112e395949392919061439a565b600060405180830381600087803b1580156112fd57600080fd5b505af1158015611311573d6000803e3d6000fd5b505087516040516370a0823160e01b8152600093506001600160a01b0390911691506370a082319061134790309060040161432f565b60206040518083038186803b15801561135f57600080fd5b505afa158015611373573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113979190613f19565b905060008661014001511561140457602086015187516040808a015160e08b015191516370a0823160e01b81526113f99493926113f291600080516020614751833981519152906370a082319061043390309060040161432f565b6000612972565b5060e086015161144b565b60808701516114489061141790876110df565b6040516370a0823160e01b8152600080516020614751833981519152906370a082319061043390309060040161432f565b90505b86604001516000805160206147318339815191528861016001518a608001518b606001518686604051611482959493929190614468565b60405180910390a2801561151b57602087015160405163a9059cbb60e01b81526000805160206147518339815191529163a9059cbb916114c791908590600401614381565b602060405180830381600087803b1580156114e157600080fd5b505af11580156114f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115199190613efd565b505b81156110d5576110d58760000151886020015184612dbb565b6080808301519084015160009061154b90846110df565b90508461014001511561155c575060005b6000805160206147518339815191526001600160a01b031663095ea7b3836115968861010001518a604001516110df90919063ffffffff16565b6040518363ffffffff1660e01b81526004016115b3929190614381565b602060405180830381600087803b1580156115cd57600080fd5b505af11580156115e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116059190613efd565b6116215760405162461bcd60e51b815260040161035c9061449f565b816001600160a01b031663bc6f02b287602001516116518861010001518a604001516110df90919063ffffffff16565b89608001518a60a001518b60c001516040518663ffffffff1660e01b815260040161168095949392919061439a565b600060405180830381600087803b15801561169a57600080fd5b505af11580156116ae573d6000803e3d6000fd5b505050506116c6858286602001518760000151612f76565b6040516370a0823160e01b8152600090611700908390600080516020614751833981519152906370a082319061043390309060040161432f565b9050856040015160008051602061473183398151915287610160015189608001518a6060015160008660405161173a959493929190614468565b60405180910390a280156117d157602086015160405163a9059cbb60e01b81526000805160206147518339815191529163a9059cbb9161177f91908590600401614381565b602060405180830381600087803b15801561179957600080fd5b505af11580156117ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d59190613efd565b50505050505050565b600083608001519050600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561182257600080fd5b505afa158015611836573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185a9190613e3c565b9050611879856020015187600001518860400151896080015187612972565b865160405163095ea7b360e01b81526001600160a01b039091169063095ea7b3906118aa9085908790600401614381565b602060405180830381600087803b1580156118c457600080fd5b505af11580156118d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fc9190613efd565b6119185760405162461bcd60e51b815260040161035c90614558565b865160408089015160808a015160a08b015160c08c0151935163c723c87f60e01b81526001600160a01b0388169563c723c87f9561195e9591949193919260040161439a565b600060405180830381600087803b15801561197857600080fd5b505af115801561198c573d6000803e3d6000fd5b50506040516370a0823160e01b8152600092506119ca91508690600080516020614751833981519152906370a082319061043390309060040161432f565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016119fa919061432f565b60206040518083038186803b158015611a1257600080fd5b505afa158015611a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4a9190613f19565b90508115611add57602088015160405163a9059cbb60e01b81526000805160206147518339815191529163a9059cbb91611a8991908690600401614381565b602060405180830381600087803b158015611aa357600080fd5b505af1158015611ab7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611adb9190613efd565b505b8015611af657611af68860000151896020015183612dbb565b87604001516000805160206147318339815191528961016001518b608001518c606001518587604051611b2d959493929190614468565b60405180910390a2505050505050505050565b600083608001519050600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015611b8857600080fd5b505afa158015611b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc09190613e3c565b9050611bdf856020015187600001518860400151896080015187612972565b86600001516001600160a01b031663095ea7b383836001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611c1f919061432f565b60206040518083038186803b158015611c3757600080fd5b505afa158015611c4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c6f9190613f19565b6040518363ffffffff1660e01b8152600401611c8c929190614381565b602060405180830381600087803b158015611ca657600080fd5b505af1158015611cba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cde9190613efd565b611cfa5760405162461bcd60e51b815260040161035c90614558565b8651608088015160a089015160c08a015160405163c723c87f60e01b81526001600160a01b0387169463c723c87f94611d3c9491938a9391929160040161439a565b600060405180830381600087803b158015611d5657600080fd5b505af1158015611d6a573d6000803e3d6000fd5b50506040516370a0823160e01b815260009250611da891508690600080516020614751833981519152906370a082319061043390309060040161432f565b90508015611e3b57602087015160405163a9059cbb60e01b81526000805160206147518339815191529163a9059cbb91611de791908590600401614381565b602060405180830381600087803b158015611e0157600080fd5b505af1158015611e15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e399190613efd565b505b6040516370a0823160e01b81526000906001600160a01b038416906370a0823190611e6a90309060040161432f565b60206040518083038186803b158015611e8257600080fd5b505afa158015611e96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eba9190613f19565b905087604001516000805160206147318339815191528961016001518b608001518c606001518587604051611b2d959493929190614468565b81600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f3057600080fd5b505afa158015611f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f689190613f19565b6060830152604051600090611f8890600190869086908690602001614427565b604051602081830303815290604052905082610140015115610e6a57600083600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015611fe357600080fd5b505afa158015611ff7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061201b9190613e3c565b90506000816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161204b919061432f565b60206040518083038186803b15801561206357600080fd5b505afa158015612077573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209b9190613f19565b905080156120d55760808501516120d09086906120be6040880160208901613e20565b6120cb6020890189613e20565b612f76565b6120e4565b6120e485858760800151613419565b6121076120f0876146dc565b8661210036889003880188613f31565b6000611534565b5050610e83565b82602001516001600160a01b0316630b63fb628360400151856040015160016040518463ffffffff1660e01b815260040161214b93929190614675565b600060405180830381600087803b15801561216557600080fd5b505af1158015612179573d6000803e3d6000fd5b505050606084015160408086015160808601519151632e7ff4ef60e11b81526001600160a01b039093169350635cffe9de926121c9926000805160206147518339815191529187906004016143f4565b602060405180830381600087803b1580156121e357600080fd5b505af11580156121f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221b9190613efd565b5082602001516001600160a01b0316630b63fb628360400151856040015160006040518463ffffffff1660e01b815260040161225993929190614675565b600060405180830381600087803b15801561227357600080fd5b505af11580156117d1573d6000803e3d6000fd5b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b81526004016122b691906143d4565b60a06040518083038186803b1580156122ce57600080fd5b505afa1580156122e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123069190613ff2565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b815260040161233c9291906143dd565b604080518083038186803b15801561235357600080fd5b505afa158015612367573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238b9190613fcf565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b81526004016123bc919061432f565b60206040518083038186803b1580156123d457600080fd5b505afa1580156123e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240c9190613f19565b9050600061241e8261048385876137c1565b9050676765c793fa10079d601b1b810494508061244686676765c793fa10079d601b1b6137c1565b106124515784612456565b846001015b9998505050505050505050565b600082608001519050600084600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b1580156124ab57600080fd5b505afa1580156124bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e39190613e3c565b905061250384602001518660000151876040015160008a60400151612972565b855160405163095ea7b360e01b81526001600160a01b039091169063095ea7b3906125349085908790600401614381565b602060405180830381600087803b15801561254e57600080fd5b505af1158015612562573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125869190613efd565b6125a25760405162461bcd60e51b815260040161035c90614558565b8551604080880151608089015160a08a015160c08b0151935163c723c87f60e01b81526001600160a01b0388169563c723c87f956125e89591949193919260040161439a565b600060405180830381600087803b15801561260257600080fd5b505af1158015612616573d6000803e3d6000fd5b50506040516370a0823160e01b81526000925060008051602061475183398151915291506370a082319061264e90309060040161432f565b60206040518083038186803b15801561266657600080fd5b505afa15801561267a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269e9190613f19565b905080866080015111156126c45760405162461bcd60e51b815260040161035c906144e7565b6126e585602001518760000151886040015189608001518a60c00151612972565b6040516370a0823160e01b8152600080516020614751833981519152906370a082319061271690309060040161432f565b60206040518083038186803b15801561272e57600080fd5b505afa158015612742573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127669190613f19565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401612796919061432f565b60206040518083038186803b1580156127ae57600080fd5b505afa1580156127c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e69190613f19565b9050811561287957602087015160405163a9059cbb60e01b81526000805160206147518339815191529163a9059cbb9161282591908690600401614381565b602060405180830381600087803b15801561283f57600080fd5b505af1158015612853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128779190613efd565b505b8015612892576128928760000151886020015183612dbb565b86604001516000805160206147318339815191528861016001518a608001518b6060015185876040516128c9959493929190614468565b60405180910390a25050505050505050565b6000818484111561296a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561292f578181015183820152602001612917565b50505050905090810190601f16801561295c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156129ad57600080fd5b505afa1580156129c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e59190613e3c565b90506000866001600160a01b0316632726b073866040518263ffffffff1660e01b8152600401612a1591906143d4565b60206040518083038186803b158015612a2d57600080fd5b505afa158015612a41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a659190613e3c565b90506000876001600160a01b0316632c2cb9fd876040518263ffffffff1660e01b8152600401612a9591906143d4565b60206040518083038186803b158015612aad57600080fd5b505afa158015612ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae59190613f19565b60405163095ea7b360e01b81529091506000805160206147518339815191529063095ea7b390612b2f90739759a6ac90977b93b58547b4a71c78317f391a28908990600401614381565b602060405180830381600087803b158015612b4957600080fd5b505af1158015612b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b819190613efd565b50604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f90612bbb9085908990600401614381565b600060405180830381600087803b158015612bd557600080fd5b505af1158015612be9573d6000803e3d6000fd5b505050506000612bf9888661381a565b9050886001600160a01b03166345e6bdcd88612c148461389d565b600003612c9e88896001600160a01b0316636c25b3468a6040518263ffffffff1660e01b8152600401612c47919061432f565b60206040518083038186803b158015612c5f57600080fd5b505afa158015612c73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c979190613f19565b89896138c4565b6040518463ffffffff1660e01b8152600401612cbc93929190614694565b600060405180830381600087803b158015612cd657600080fd5b505af1158015612cea573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b038c169250639bb8f8389150612d1e908a9030908690600401614675565b600060405180830381600087803b158015612d3857600080fd5b505af1158015612d4c573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038b16925063ef693bed9150612d7e9030908990600401614381565b600060405180830381600087803b158015612d9857600080fd5b505af1158015612dac573d6000803e3d6000fd5b50505050505050505050505050565b6000836001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015612df657600080fd5b505afa158015612e0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2e9190613e3c565b90506001600160a01b03811673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415612eef57604051632e1a7d4d60e01b81526001600160a01b03821690632e1a7d4d90612e819085906004016143d4565b600060405180830381600087803b158015612e9b57600080fd5b505af1158015612eaf573d6000803e3d6000fd5b50506040516001600160a01b038616925084156108fc02915084906000818181858888f19350505050158015612ee9573d6000803e3d6000fd5b50610e83565b60405163a9059cbb60e01b81526001600160a01b0382169063a9059cbb90612f1d9086908690600401614381565b602060405180830381600087803b158015612f3757600080fd5b505af1158015612f4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f6f9190613efd565b5050505050565b600084600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015612fb557600080fd5b505afa158015612fc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fed9190613e3c565b90506000816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161301d919061432f565b60206040518083038186803b15801561303557600080fd5b505afa158015613049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306d9190613f19565b865160405163095ea7b360e01b81529192506001600160a01b0384169163095ea7b39161309e918590600401614381565b600060405180830381600087803b1580156130b857600080fd5b505af11580156130cc573d6000803e3d6000fd5b505050506000846001600160a01b0316632726b07388604001516040518263ffffffff1660e01b815260040161310291906143d4565b60206040518083038186803b15801561311a57600080fd5b505afa15801561312e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131529190613e3c565b90506000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b15801561318f57600080fd5b505afa1580156131a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c79190613e3c565b8851604051633b4da69f60e01b81529192506001600160a01b031690633b4da69f906131f99085908790600401614381565b600060405180830381600087803b15801561321357600080fd5b505af1158015613227573d6000803e3d6000fd5b50505050856001600160a01b03166345e6bdcd89604001516132556132508c600001518861381a565b61389d565b613266858a888f606001518f613a08565b6040518463ffffffff1660e01b815260040161328493929190614694565b600060405180830381600087803b15801561329e57600080fd5b505af11580156132b2573d6000803e3d6000fd5b50505060408901516001600160a01b038816915063f9f30db690306132e28b676765c793fa10079d601b1b6137c1565b6040518463ffffffff1660e01b815260040161330093929190614675565b600060405180830381600087803b15801561331a57600080fd5b505af115801561332e573d6000803e3d6000fd5b50506040516328ec8bf160e21b81526001600160a01b038416925063a3b22fc4915061337290739759a6ac90977b93b58547b4a71c78317f391a289060040161432f565b600060405180830381600087803b15801561338c57600080fd5b505af11580156133a0573d6000803e3d6000fd5b505060405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a28925063ef693bed91506133dd9030908b90600401614381565b600060405180830381600087803b1580156133f757600080fd5b505af115801561340b573d6000803e3d6000fd5b505050505050505050505050565b600061342b6040840160208501613e20565b6001600160a01b0316632726b07385604001516040518263ffffffff1660e01b815260040161345a91906143d4565b60206040518083038186803b15801561347257600080fd5b505afa158015613486573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134aa9190613e3c565b905060006134be6040850160208601613e20565b6001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156134f657600080fd5b505afa15801561350a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352e9190613e3c565b90506135406040850160208601613e20565b6001600160a01b03166345e6bdcd866040015160006135788589600001602081019061356c9190613e20565b888c606001518b613a08565b6040518463ffffffff1660e01b815260040161359693929190614694565b600060405180830381600087803b1580156135b057600080fd5b505af11580156135c4573d6000803e3d6000fd5b506135d9925050506040850160208601613e20565b6001600160a01b031663f9f30db68660400151306135f687613b8a565b6040518463ffffffff1660e01b815260040161361493929190614675565b600060405180830381600087803b15801561362e57600080fd5b505af1158015613642573d6000803e3d6000fd5b5050604051634538c4eb60e01b81526001600160a01b0384169250634538c4eb9150613688903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614343565b60206040518083038186803b1580156136a057600080fd5b505afa1580156136b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d89190613f19565b61374f576040516328ec8bf160e21b81526001600160a01b0382169063a3b22fc49061371c90739759a6ac90977b93b58547b4a71c78317f391a289060040161432f565b600060405180830381600087803b15801561373657600080fd5b505af115801561374a573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed906137889030908790600401614381565b600060405180830381600087803b1580156137a257600080fd5b505af11580156137b6573d6000803e3d6000fd5b505050505050505050565b6000826137d05750600061113c565b828202828482816137dd57fe5b04146111395760405162461bcd60e51b81526004018080602001828103825260218152602001806147926021913960400191505060405180910390fd5b6000611139836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561385857600080fd5b505afa15801561386c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138909190613f19565b8390601203600a0a6137c1565b8060008112156138bf5760405162461bcd60e51b815260040161035c906145a2565b919050565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b81526004016138f391906143d4565b60a06040518083038186803b15801561390b57600080fd5b505afa15801561391f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139439190613ff2565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b81526004016139799291906143dd565b604080518083038186803b15801561399057600080fd5b505afa1580156139a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139c89190613fcf565b9150506139dd8287816139d757fe5b0461389d565b9250808311156139f8576139f08161389d565b6000036139fd565b826000035b979650505050505050565b600080856001600160a01b03166344e2a5a8856040518263ffffffff1660e01b8152600401613a3791906143d4565b602060405180830381600087803b158015613a5157600080fd5b505af1158015613a65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a899190613f19565b90506000876001600160a01b0316636c25b346876040518263ffffffff1660e01b8152600401613ab9919061432f565b60206040518083038186803b158015613ad157600080fd5b505afa158015613ae5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b099190613f19565b9050613b2084676765c793fa10079d601b1b6137c1565b811015613b7f57613b4b82613b448361048388676765c793fa10079d601b1b6137c1565b816139d757fe5b9250613b6284676765c793fa10079d601b1b6137c1565b613b6c84846137c1565b10613b775782613b7c565b826001015b92505b505095945050505050565b600061113c82676765c793fa10079d601b1b6137c1565b80356138bf816146e8565b80356138bf81614700565b600082601f830112613bc7578081fd5b813567ffffffffffffffff811115613bdb57fe5b613bee601f8201601f19166020016146b8565b818152846020838601011115613c02578283fd5b816020850160208301379081016020019190915292915050565b600060a08284031215613c2d578081fd5b60405160a0810181811067ffffffffffffffff82111715613c4a57fe5b6040529050808235613c5b816146e8565b81526020830135613c6b816146e8565b60208201526040830135613c7e816146e8565b60408201526060830135613c91816146e8565b60608201526080830135613ca4816146e8565b6080919091015292915050565b6000610180808385031215613cc4578182fd5b613ccd816146b8565b915050613cd982613ba1565b8152613ce760208301613ba1565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a082015260c082013560c082015260e082013560e0820152610100808301358183015250610120808301358183015250610140613d4e818401613bac565b908201526101608281013567ffffffffffffffff811115613d6e57600080fd5b613d7a85828601613bb7565b82840152505092915050565b600060e08284031215613d97578081fd5b613da160e06146b8565b9050613dac82613ba1565b8152613dba60208301613ba1565b6020820152604082013560408201526060820135606082015260808201356080820152613de960a08301613ba1565b60a082015260c082013567ffffffffffffffff811115613e0857600080fd5b613e1484828501613bb7565b60c08301525092915050565b600060208284031215613e31578081fd5b8135611139816146e8565b600060208284031215613e4d578081fd5b8151611139816146e8565b60008060008060008060a08789031215613e70578182fd5b8635613e7b816146e8565b95506020870135613e8b816146e8565b94506040870135935060608701359250608087013567ffffffffffffffff80821115613eb5578384fd5b818901915089601f830112613ec8578384fd5b813581811115613ed6578485fd5b8a6020828501011115613ee7578485fd5b6020830194508093505050509295509295509295565b600060208284031215613f0e578081fd5b815161113981614700565b600060208284031215613f2a578081fd5b5051919050565b600060a08284031215613f42578081fd5b6111398383613c1c565b600080600083850360e0811215613f61578182fd5b843567ffffffffffffffff80821115613f78578384fd5b9086019060e08289031215613f8b578384fd5b90945060208601359080821115613fa0578384fd5b50613fad87828801613cb1565b93505060a0603f1982011215613fc1578182fd5b506040840190509250925092565b60008060408385031215613fe1578182fd5b505080516020909101519092909150565b600080600080600060a08688031215614009578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6000806000806101008587031215614047578182fd5b843560ff81168114614057578283fd5b9350602085013567ffffffffffffffff80821115614073578384fd5b61407f88838901613d86565b94506040870135915080821115614094578384fd5b506140a187828801613cb1565b9250506140b18660608701613c1c565b905092959194509250565b6001600160a01b03169052565b15159052565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b8181101561411e57602081850181015186830182015201614102565b8181111561412f5782602083870101525b50601f01601f19169290920160200192915050565b803561414f816146e8565b6001600160a01b03908116835260208201359061416b826146e8565b9081166020840152604082013590614182826146e8565b9081166040840152606082013590614199826146e8565b90811660608401526080820135906141b0826146e8565b808216608085015250505050565b60006101806141ce8484516140bc565b60208301516141e060208601826140bc565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e083015160e085015261010080840151818601525061012080840151818601525061014080840151614248828701826140c9565b5050610160808401518282870152614262838701826140f9565b9695505050505050565b60008135614279816146e8565b6001600160a01b039081168452602083013590614295826146e8565b808216602086015260408401356040860152606084013560608601526080840135608086015260a084013591506142cb826146e8565b1660a084015260c082013536839003601e190181126142e8578182fd5b8201803567ffffffffffffffff811115614300578283fd5b80360384131561430e578283fd5b60e060c086015261432660e0860182602085016140cf565b95945050505050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03868116825260208201869052604082018590528316606082015260a0608082018190526000906139fd908301846140f9565b90815260200190565b9182526001600160a01b0316602082015260400190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614262908301846140f9565b600061010060ff871683528060208401526144448184018761426c565b9050828103604084015261445881866141be565b9150506143266060830184614144565b600060a0825261447b60a08301886140f9565b90508560208301528460408301528360608301528260808301529695505050505050565b60208082526028908201527f4d5041202f20436f756c64206e6f7420617070726f76652045786368616e676560408201526720666f722044414960c01b606082015260800190565b60208082526015908201527418d85b9b9bdd081c995c185e48185b1b081919589d605a1b604082015260600190565b60208082526022908201527f63616e6e6f7420636c6f736520746f2044414920696620464c206e6f74207573604082015261195960f21b606082015260800190565b6020808252602a908201527f4d5041202f20436f756c64206e6f7420617070726f76652045786368616e6765604082015269103337b9102a37b5b2b760b11b606082015260800190565b6020808252600f908201526e696e743235362d6f766572666c6f7760881b604082015260600190565b60208082526025908201527f6d70612d726563656976652d7265717565737465642d616d6f756e742d6d69736040820152640dac2e8c6d60db1b606082015260800190565b60208082526014908201527336b83096bab73a393ab9ba32b216b632b73232b960611b604082015260600190565b6020808252601f908201527f7468697320636f64652073686f756c6420626520756e726561636861626c6500604082015260600190565b9283526001600160a01b03919091166020830152604082015260600190565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff811182821017156146d457fe5b604052919050565b600061113c3683613d86565b6001600160a01b03811681146146fd57600080fd5b50565b80151581146146fd57600080fdfe64656372656173654d756c7469706c655769746864726177436f6c6c61746572616cead01ff65532b6ee1646408ed4a14f45b5ee091a71e9bb1f579c0a44d59230110000000000000000000000006b175474e89094c44da98b954eedeac495271d0f696e6372656173654d756c7469706c654465706f736974436f6c6c61746572616c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220f80eb6141e0e7d3fc2e5d49a3dfc5c4f794a82b855b832a91ca49631f8197a7a64736f6c63430007060033

Deployed Bytecode

0x6080604052600436106100c25760003560e01c80634a9b4e0c1161007f578063ad5c464811610059578063ad5c4648146101ed578063cedee4ef1461020f578063e0bab4c414610222578063f85c2ce314610237576100c2565b80634a9b4e0c1461019a57806371ae86a5146101ba57806399e13c1a146101da576100c2565b80630521a3c7146100c45780631c9ea1e0146100e45780631f41f7b61461010457806323e30c8b1461012457806334f674731461015a5780633b9b4d951461017a575b005b3480156100d057600080fd5b506100c26100df366004613f4c565b61024c565b3480156100f057600080fd5b506100c26100ff366004613f4c565b6102b2565b34801561011057600080fd5b506100c261011f366004613f4c565b6102eb565b34801561013057600080fd5b5061014461013f366004613e58565b610372565b60405161015191906143d4565b60405180910390f35b34801561016657600080fd5b506100c2610175366004613f4c565b61066f565b34801561018657600080fd5b506100c2610195366004613f4c565b6106b5565b3480156101a657600080fd5b506100c26101b5366004613f4c565b61071c565b3480156101c657600080fd5b506100c26101d5366004613f4c565b610774565b6100c26101e8366004613f4c565b610912565b3480156101f957600080fd5b50610202610a7d565b604051610151919061432f565b6100c261021d366004613f4c565b610a95565b34801561022e57600080fd5b50610202610d68565b34801561024357600080fd5b50610202610d7a565b60405180606001604052806022815260200161470f60229139826102766060840160408501613e20565b6101608201515161028a5761016082018390525b610295868686610d92565b506040805160208101909152600081526101609091015250505050565b604080518082018252601081526f64656372656173654d756c7469706c6560801b60208201529083906102769060608501908501613e20565b6040805180820182526011815270636c6f73655661756c744578697444616960781b60208201529083906103259060608501908501613e20565b610160820151516103395761016082018390525b610140850151156103655760405162461bcd60e51b815260040161035c90614516565b60405180910390fd5b6102958686866003610e89565b60008080808061038486880188614031565b935093509350935080606001516001600160a01b0316336001600160a01b0316146103c15760405162461bcd60e51b815260040161035c90614610565b60006103cd8a8a6110df565b90507f9c6641b21946115d10f3f55df9bec5752ec06d40dc9250b1cc6560549764600e6104898461010001516000805160206147518339815191526001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610433919061432f565b60206040518083038186803b15801561044b57600080fd5b505afa15801561045f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104839190613f19565b90611142565b826040516104989291906146aa565b60405180910390a16040516370a0823160e01b8152600080516020614751833981519152906370a08231906104d190309060040161432f565b60206040518083038186803b1580156104e957600080fd5b505afa1580156104fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105219190613f19565b6101008401516080850151610535916110df565b11156105535760405162461bcd60e51b815260040161035c906145cb565b60ff8516610567576105678484848c611184565b8460ff166001141561057f5761057f8484848c611534565b8460ff166002141561059c5761059c848484848760a001516117da565b8460ff16600314156105b9576105b9848484848760a00151611b40565b606082015160405163095ea7b360e01b81526001600160a01b038d169163095ea7b3916105eb91908590600401614381565b602060405180830381600087803b15801561060557600080fd5b505af1158015610619573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063d9190613efd565b507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd99c9b505050505050505050505050565b604080518082018252601b81527f64656372656173654d756c7469706c655769746864726177446169000000000060208201529083906102769060608501908501613e20565b604080518082018252601881527f636c6f73655661756c7445786974436f6c6c61746572616c000000000000000060208201529083906106fb9060608501908501613e20565b6101608201515161070f5761016082018390525b6102958686866002610e89565b604080518082018252601081526f696e6372656173654d756c7469706c6560801b60208201529083906107559060608501908501613e20565b610160820151516107695761016082018390525b610295868686611ef3565b604080518082018252601a81527f696e6372656173654d756c7469706c654465706f73697444616900000000000060208201529083906107ba9060608501908501613e20565b610160820151516107ce5761016082018390525b8461014001511561086b576101008501516040516323b872dd60e01b8152600080516020614751833981519152916323b872dd9161081391339130919060040161435d565b602060405180830381600087803b15801561082d57600080fd5b505af1158015610841573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108659190613efd565b50610769565b6000805160206147518339815191526323b872dd336108906060880160408901613e20565b8861010001516040518463ffffffff1660e01b81526004016108b49392919061435d565b602060405180830381600087803b1580156108ce57600080fd5b505af11580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109069190613efd565b50610295868686611ef3565b60408051808201825260118152701bdc195b935d5b1d1a5c1b1e55985d5b1d607a1b602082015290839061094c9060608501908501613e20565b610160820151516109605761016082018390525b84600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561099d57600080fd5b505afa1580156109b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d59190613f19565b60608601526109ea6040850160208601613e20565b6001600160a01b0316636090dec58660600151306040518363ffffffff1660e01b8152600401610a1b9291906143dd565b602060405180830381600087803b158015610a3557600080fd5b505af1158015610a49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6d9190613f19565b6040860152610295868686610a95565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6040518060600160405280602181526020016147716021913982610abf6060840160408501613e20565b61016082015151610ad35761016082018390525b600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1257600080fd5b505afa158015610b26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4a9190613e3c565b90506001600160a01b03811673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415610c6857806001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610bac57600080fd5b505af1158015610bc0573d6000803e3d6000fd5b5050505061014087015115159050610c63576001600160a01b03811663a9059cbb610bf16060880160408901613e20565b346040518363ffffffff1660e01b8152600401610c0f929190614381565b602060405180830381600087803b158015610c2957600080fd5b505af1158015610c3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c619190613efd565b505b610d3f565b610140860151610cb6576001600160a01b0381166323b872dd33610c926060890160408a01613e20565b8961012001516040518463ffffffff1660e01b8152600401610c0f9392919061435d565b6101208601516040516323b872dd60e01b81526001600160a01b038316916323b872dd91610ceb91339130919060040161435d565b602060405180830381600087803b158015610d0557600080fd5b505af1158015610d19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3d9190613efd565b505b610d4a878787611ef3565b50506040805160208101909152600081526101609091015250505050565b60008051602061475183398151915281565b739759a6ac90977b93b58547b4a71c78317f391a2881565b81600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dcf57600080fd5b505afa158015610de3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e079190613f19565b6060830152604051600090610e26908290869086908690602001614427565b604051602081830303815290604052905082610140015115610e6a57610e65610e4e856146dc565b84610e5e36869003860186613f31565b6000611184565b610e83565b610e83610e7c36849003840184613f31565b848361210e565b50505050565b82600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ec657600080fd5b505afa158015610eda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efe9190613f19565b60608401526000610f156040840160208501613e20565b6001600160a01b0316632726b07385604001516040518263ffffffff1660e01b8152600401610f4491906143d4565b60206040518083038186803b158015610f5c57600080fd5b505afa158015610f70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f949190613e3c565b90506000610fa86040850160208601613e20565b6001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015610fe057600080fd5b505afa158015610ff4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110189190613e3c565b9050600061102c8284858960600151612287565b608087018190526040519091506000906110509086908a908a908a90602001614427565b60408051601f1981840301815291905261014088015190915061108b5761108661107f36889003880188613f31565b888361210e565b6110d5565b8460ff16600214156110bd576110866110a3896146dc565b886110b3368a90038a018a613f31565b8a60a00151612463565b60405162461bcd60e51b815260040161035c9061463e565b5050505050505050565b600082820183811015611139576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600061113983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506128db565b60808201516101408401516000906111ae5760e085015160808601516111a991611142565b6111b1565b60005b90506111e6846020015186600001518760400151846111e18a60c001518b60a001516110df90919063ffffffff16565b612972565b8551604080880151905163095ea7b360e01b81526001600160a01b039092169163095ea7b39161121b91869190600401614381565b602060405180830381600087803b15801561123557600080fd5b505af1158015611249573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126d9190613efd565b6112895760405162461bcd60e51b815260040161035c90614558565b816001600160a01b031663c723c87f876000015188604001516112b9878a608001516110df90919063ffffffff16565b8a60a001518b60c001516040518663ffffffff1660e01b81526004016112e395949392919061439a565b600060405180830381600087803b1580156112fd57600080fd5b505af1158015611311573d6000803e3d6000fd5b505087516040516370a0823160e01b8152600093506001600160a01b0390911691506370a082319061134790309060040161432f565b60206040518083038186803b15801561135f57600080fd5b505afa158015611373573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113979190613f19565b905060008661014001511561140457602086015187516040808a015160e08b015191516370a0823160e01b81526113f99493926113f291600080516020614751833981519152906370a082319061043390309060040161432f565b6000612972565b5060e086015161144b565b60808701516114489061141790876110df565b6040516370a0823160e01b8152600080516020614751833981519152906370a082319061043390309060040161432f565b90505b86604001516000805160206147318339815191528861016001518a608001518b606001518686604051611482959493929190614468565b60405180910390a2801561151b57602087015160405163a9059cbb60e01b81526000805160206147518339815191529163a9059cbb916114c791908590600401614381565b602060405180830381600087803b1580156114e157600080fd5b505af11580156114f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115199190613efd565b505b81156110d5576110d58760000151886020015184612dbb565b6080808301519084015160009061154b90846110df565b90508461014001511561155c575060005b6000805160206147518339815191526001600160a01b031663095ea7b3836115968861010001518a604001516110df90919063ffffffff16565b6040518363ffffffff1660e01b81526004016115b3929190614381565b602060405180830381600087803b1580156115cd57600080fd5b505af11580156115e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116059190613efd565b6116215760405162461bcd60e51b815260040161035c9061449f565b816001600160a01b031663bc6f02b287602001516116518861010001518a604001516110df90919063ffffffff16565b89608001518a60a001518b60c001516040518663ffffffff1660e01b815260040161168095949392919061439a565b600060405180830381600087803b15801561169a57600080fd5b505af11580156116ae573d6000803e3d6000fd5b505050506116c6858286602001518760000151612f76565b6040516370a0823160e01b8152600090611700908390600080516020614751833981519152906370a082319061043390309060040161432f565b9050856040015160008051602061473183398151915287610160015189608001518a6060015160008660405161173a959493929190614468565b60405180910390a280156117d157602086015160405163a9059cbb60e01b81526000805160206147518339815191529163a9059cbb9161177f91908590600401614381565b602060405180830381600087803b15801561179957600080fd5b505af11580156117ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d59190613efd565b50505050505050565b600083608001519050600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561182257600080fd5b505afa158015611836573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185a9190613e3c565b9050611879856020015187600001518860400151896080015187612972565b865160405163095ea7b360e01b81526001600160a01b039091169063095ea7b3906118aa9085908790600401614381565b602060405180830381600087803b1580156118c457600080fd5b505af11580156118d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fc9190613efd565b6119185760405162461bcd60e51b815260040161035c90614558565b865160408089015160808a015160a08b015160c08c0151935163c723c87f60e01b81526001600160a01b0388169563c723c87f9561195e9591949193919260040161439a565b600060405180830381600087803b15801561197857600080fd5b505af115801561198c573d6000803e3d6000fd5b50506040516370a0823160e01b8152600092506119ca91508690600080516020614751833981519152906370a082319061043390309060040161432f565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016119fa919061432f565b60206040518083038186803b158015611a1257600080fd5b505afa158015611a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4a9190613f19565b90508115611add57602088015160405163a9059cbb60e01b81526000805160206147518339815191529163a9059cbb91611a8991908690600401614381565b602060405180830381600087803b158015611aa357600080fd5b505af1158015611ab7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611adb9190613efd565b505b8015611af657611af68860000151896020015183612dbb565b87604001516000805160206147318339815191528961016001518b608001518c606001518587604051611b2d959493929190614468565b60405180910390a2505050505050505050565b600083608001519050600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015611b8857600080fd5b505afa158015611b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc09190613e3c565b9050611bdf856020015187600001518860400151896080015187612972565b86600001516001600160a01b031663095ea7b383836001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611c1f919061432f565b60206040518083038186803b158015611c3757600080fd5b505afa158015611c4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c6f9190613f19565b6040518363ffffffff1660e01b8152600401611c8c929190614381565b602060405180830381600087803b158015611ca657600080fd5b505af1158015611cba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cde9190613efd565b611cfa5760405162461bcd60e51b815260040161035c90614558565b8651608088015160a089015160c08a015160405163c723c87f60e01b81526001600160a01b0387169463c723c87f94611d3c9491938a9391929160040161439a565b600060405180830381600087803b158015611d5657600080fd5b505af1158015611d6a573d6000803e3d6000fd5b50506040516370a0823160e01b815260009250611da891508690600080516020614751833981519152906370a082319061043390309060040161432f565b90508015611e3b57602087015160405163a9059cbb60e01b81526000805160206147518339815191529163a9059cbb91611de791908590600401614381565b602060405180830381600087803b158015611e0157600080fd5b505af1158015611e15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e399190613efd565b505b6040516370a0823160e01b81526000906001600160a01b038416906370a0823190611e6a90309060040161432f565b60206040518083038186803b158015611e8257600080fd5b505afa158015611e96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eba9190613f19565b905087604001516000805160206147318339815191528961016001518b608001518c606001518587604051611b2d959493929190614468565b81600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f3057600080fd5b505afa158015611f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f689190613f19565b6060830152604051600090611f8890600190869086908690602001614427565b604051602081830303815290604052905082610140015115610e6a57600083600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015611fe357600080fd5b505afa158015611ff7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061201b9190613e3c565b90506000816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161204b919061432f565b60206040518083038186803b15801561206357600080fd5b505afa158015612077573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209b9190613f19565b905080156120d55760808501516120d09086906120be6040880160208901613e20565b6120cb6020890189613e20565b612f76565b6120e4565b6120e485858760800151613419565b6121076120f0876146dc565b8661210036889003880188613f31565b6000611534565b5050610e83565b82602001516001600160a01b0316630b63fb628360400151856040015160016040518463ffffffff1660e01b815260040161214b93929190614675565b600060405180830381600087803b15801561216557600080fd5b505af1158015612179573d6000803e3d6000fd5b505050606084015160408086015160808601519151632e7ff4ef60e11b81526001600160a01b039093169350635cffe9de926121c9926000805160206147518339815191529187906004016143f4565b602060405180830381600087803b1580156121e357600080fd5b505af11580156121f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221b9190613efd565b5082602001516001600160a01b0316630b63fb628360400151856040015160006040518463ffffffff1660e01b815260040161225993929190614675565b600060405180830381600087803b15801561227357600080fd5b505af11580156117d1573d6000803e3d6000fd5b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b81526004016122b691906143d4565b60a06040518083038186803b1580156122ce57600080fd5b505afa1580156122e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123069190613ff2565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b815260040161233c9291906143dd565b604080518083038186803b15801561235357600080fd5b505afa158015612367573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238b9190613fcf565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b81526004016123bc919061432f565b60206040518083038186803b1580156123d457600080fd5b505afa1580156123e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240c9190613f19565b9050600061241e8261048385876137c1565b9050676765c793fa10079d601b1b810494508061244686676765c793fa10079d601b1b6137c1565b106124515784612456565b846001015b9998505050505050505050565b600082608001519050600084600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b1580156124ab57600080fd5b505afa1580156124bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e39190613e3c565b905061250384602001518660000151876040015160008a60400151612972565b855160405163095ea7b360e01b81526001600160a01b039091169063095ea7b3906125349085908790600401614381565b602060405180830381600087803b15801561254e57600080fd5b505af1158015612562573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125869190613efd565b6125a25760405162461bcd60e51b815260040161035c90614558565b8551604080880151608089015160a08a015160c08b0151935163c723c87f60e01b81526001600160a01b0388169563c723c87f956125e89591949193919260040161439a565b600060405180830381600087803b15801561260257600080fd5b505af1158015612616573d6000803e3d6000fd5b50506040516370a0823160e01b81526000925060008051602061475183398151915291506370a082319061264e90309060040161432f565b60206040518083038186803b15801561266657600080fd5b505afa15801561267a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061269e9190613f19565b905080866080015111156126c45760405162461bcd60e51b815260040161035c906144e7565b6126e585602001518760000151886040015189608001518a60c00151612972565b6040516370a0823160e01b8152600080516020614751833981519152906370a082319061271690309060040161432f565b60206040518083038186803b15801561272e57600080fd5b505afa158015612742573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127669190613f19565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401612796919061432f565b60206040518083038186803b1580156127ae57600080fd5b505afa1580156127c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e69190613f19565b9050811561287957602087015160405163a9059cbb60e01b81526000805160206147518339815191529163a9059cbb9161282591908690600401614381565b602060405180830381600087803b15801561283f57600080fd5b505af1158015612853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128779190613efd565b505b8015612892576128928760000151886020015183612dbb565b86604001516000805160206147318339815191528861016001518a608001518b6060015185876040516128c9959493929190614468565b60405180910390a25050505050505050565b6000818484111561296a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561292f578181015183820152602001612917565b50505050905090810190601f16801561295c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156129ad57600080fd5b505afa1580156129c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e59190613e3c565b90506000866001600160a01b0316632726b073866040518263ffffffff1660e01b8152600401612a1591906143d4565b60206040518083038186803b158015612a2d57600080fd5b505afa158015612a41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a659190613e3c565b90506000876001600160a01b0316632c2cb9fd876040518263ffffffff1660e01b8152600401612a9591906143d4565b60206040518083038186803b158015612aad57600080fd5b505afa158015612ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae59190613f19565b60405163095ea7b360e01b81529091506000805160206147518339815191529063095ea7b390612b2f90739759a6ac90977b93b58547b4a71c78317f391a28908990600401614381565b602060405180830381600087803b158015612b4957600080fd5b505af1158015612b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b819190613efd565b50604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f90612bbb9085908990600401614381565b600060405180830381600087803b158015612bd557600080fd5b505af1158015612be9573d6000803e3d6000fd5b505050506000612bf9888661381a565b9050886001600160a01b03166345e6bdcd88612c148461389d565b600003612c9e88896001600160a01b0316636c25b3468a6040518263ffffffff1660e01b8152600401612c47919061432f565b60206040518083038186803b158015612c5f57600080fd5b505afa158015612c73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c979190613f19565b89896138c4565b6040518463ffffffff1660e01b8152600401612cbc93929190614694565b600060405180830381600087803b158015612cd657600080fd5b505af1158015612cea573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b038c169250639bb8f8389150612d1e908a9030908690600401614675565b600060405180830381600087803b158015612d3857600080fd5b505af1158015612d4c573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038b16925063ef693bed9150612d7e9030908990600401614381565b600060405180830381600087803b158015612d9857600080fd5b505af1158015612dac573d6000803e3d6000fd5b50505050505050505050505050565b6000836001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015612df657600080fd5b505afa158015612e0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2e9190613e3c565b90506001600160a01b03811673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415612eef57604051632e1a7d4d60e01b81526001600160a01b03821690632e1a7d4d90612e819085906004016143d4565b600060405180830381600087803b158015612e9b57600080fd5b505af1158015612eaf573d6000803e3d6000fd5b50506040516001600160a01b038616925084156108fc02915084906000818181858888f19350505050158015612ee9573d6000803e3d6000fd5b50610e83565b60405163a9059cbb60e01b81526001600160a01b0382169063a9059cbb90612f1d9086908690600401614381565b602060405180830381600087803b158015612f3757600080fd5b505af1158015612f4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f6f9190613efd565b5050505050565b600084600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015612fb557600080fd5b505afa158015612fc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fed9190613e3c565b90506000816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161301d919061432f565b60206040518083038186803b15801561303557600080fd5b505afa158015613049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306d9190613f19565b865160405163095ea7b360e01b81529192506001600160a01b0384169163095ea7b39161309e918590600401614381565b600060405180830381600087803b1580156130b857600080fd5b505af11580156130cc573d6000803e3d6000fd5b505050506000846001600160a01b0316632726b07388604001516040518263ffffffff1660e01b815260040161310291906143d4565b60206040518083038186803b15801561311a57600080fd5b505afa15801561312e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131529190613e3c565b90506000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b15801561318f57600080fd5b505afa1580156131a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c79190613e3c565b8851604051633b4da69f60e01b81529192506001600160a01b031690633b4da69f906131f99085908790600401614381565b600060405180830381600087803b15801561321357600080fd5b505af1158015613227573d6000803e3d6000fd5b50505050856001600160a01b03166345e6bdcd89604001516132556132508c600001518861381a565b61389d565b613266858a888f606001518f613a08565b6040518463ffffffff1660e01b815260040161328493929190614694565b600060405180830381600087803b15801561329e57600080fd5b505af11580156132b2573d6000803e3d6000fd5b50505060408901516001600160a01b038816915063f9f30db690306132e28b676765c793fa10079d601b1b6137c1565b6040518463ffffffff1660e01b815260040161330093929190614675565b600060405180830381600087803b15801561331a57600080fd5b505af115801561332e573d6000803e3d6000fd5b50506040516328ec8bf160e21b81526001600160a01b038416925063a3b22fc4915061337290739759a6ac90977b93b58547b4a71c78317f391a289060040161432f565b600060405180830381600087803b15801561338c57600080fd5b505af11580156133a0573d6000803e3d6000fd5b505060405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a28925063ef693bed91506133dd9030908b90600401614381565b600060405180830381600087803b1580156133f757600080fd5b505af115801561340b573d6000803e3d6000fd5b505050505050505050505050565b600061342b6040840160208501613e20565b6001600160a01b0316632726b07385604001516040518263ffffffff1660e01b815260040161345a91906143d4565b60206040518083038186803b15801561347257600080fd5b505afa158015613486573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134aa9190613e3c565b905060006134be6040850160208601613e20565b6001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156134f657600080fd5b505afa15801561350a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352e9190613e3c565b90506135406040850160208601613e20565b6001600160a01b03166345e6bdcd866040015160006135788589600001602081019061356c9190613e20565b888c606001518b613a08565b6040518463ffffffff1660e01b815260040161359693929190614694565b600060405180830381600087803b1580156135b057600080fd5b505af11580156135c4573d6000803e3d6000fd5b506135d9925050506040850160208601613e20565b6001600160a01b031663f9f30db68660400151306135f687613b8a565b6040518463ffffffff1660e01b815260040161361493929190614675565b600060405180830381600087803b15801561362e57600080fd5b505af1158015613642573d6000803e3d6000fd5b5050604051634538c4eb60e01b81526001600160a01b0384169250634538c4eb9150613688903090739759a6ac90977b93b58547b4a71c78317f391a2890600401614343565b60206040518083038186803b1580156136a057600080fd5b505afa1580156136b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d89190613f19565b61374f576040516328ec8bf160e21b81526001600160a01b0382169063a3b22fc49061371c90739759a6ac90977b93b58547b4a71c78317f391a289060040161432f565b600060405180830381600087803b15801561373657600080fd5b505af115801561374a573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed906137889030908790600401614381565b600060405180830381600087803b1580156137a257600080fd5b505af11580156137b6573d6000803e3d6000fd5b505050505050505050565b6000826137d05750600061113c565b828202828482816137dd57fe5b04146111395760405162461bcd60e51b81526004018080602001828103825260218152602001806147926021913960400191505060405180910390fd5b6000611139836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b15801561385857600080fd5b505afa15801561386c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138909190613f19565b8390601203600a0a6137c1565b8060008112156138bf5760405162461bcd60e51b815260040161035c906145a2565b919050565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b81526004016138f391906143d4565b60a06040518083038186803b15801561390b57600080fd5b505afa15801561391f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139439190613ff2565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b81526004016139799291906143dd565b604080518083038186803b15801561399057600080fd5b505afa1580156139a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139c89190613fcf565b9150506139dd8287816139d757fe5b0461389d565b9250808311156139f8576139f08161389d565b6000036139fd565b826000035b979650505050505050565b600080856001600160a01b03166344e2a5a8856040518263ffffffff1660e01b8152600401613a3791906143d4565b602060405180830381600087803b158015613a5157600080fd5b505af1158015613a65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a899190613f19565b90506000876001600160a01b0316636c25b346876040518263ffffffff1660e01b8152600401613ab9919061432f565b60206040518083038186803b158015613ad157600080fd5b505afa158015613ae5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b099190613f19565b9050613b2084676765c793fa10079d601b1b6137c1565b811015613b7f57613b4b82613b448361048388676765c793fa10079d601b1b6137c1565b816139d757fe5b9250613b6284676765c793fa10079d601b1b6137c1565b613b6c84846137c1565b10613b775782613b7c565b826001015b92505b505095945050505050565b600061113c82676765c793fa10079d601b1b6137c1565b80356138bf816146e8565b80356138bf81614700565b600082601f830112613bc7578081fd5b813567ffffffffffffffff811115613bdb57fe5b613bee601f8201601f19166020016146b8565b818152846020838601011115613c02578283fd5b816020850160208301379081016020019190915292915050565b600060a08284031215613c2d578081fd5b60405160a0810181811067ffffffffffffffff82111715613c4a57fe5b6040529050808235613c5b816146e8565b81526020830135613c6b816146e8565b60208201526040830135613c7e816146e8565b60408201526060830135613c91816146e8565b60608201526080830135613ca4816146e8565b6080919091015292915050565b6000610180808385031215613cc4578182fd5b613ccd816146b8565b915050613cd982613ba1565b8152613ce760208301613ba1565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a082015260c082013560c082015260e082013560e0820152610100808301358183015250610120808301358183015250610140613d4e818401613bac565b908201526101608281013567ffffffffffffffff811115613d6e57600080fd5b613d7a85828601613bb7565b82840152505092915050565b600060e08284031215613d97578081fd5b613da160e06146b8565b9050613dac82613ba1565b8152613dba60208301613ba1565b6020820152604082013560408201526060820135606082015260808201356080820152613de960a08301613ba1565b60a082015260c082013567ffffffffffffffff811115613e0857600080fd5b613e1484828501613bb7565b60c08301525092915050565b600060208284031215613e31578081fd5b8135611139816146e8565b600060208284031215613e4d578081fd5b8151611139816146e8565b60008060008060008060a08789031215613e70578182fd5b8635613e7b816146e8565b95506020870135613e8b816146e8565b94506040870135935060608701359250608087013567ffffffffffffffff80821115613eb5578384fd5b818901915089601f830112613ec8578384fd5b813581811115613ed6578485fd5b8a6020828501011115613ee7578485fd5b6020830194508093505050509295509295509295565b600060208284031215613f0e578081fd5b815161113981614700565b600060208284031215613f2a578081fd5b5051919050565b600060a08284031215613f42578081fd5b6111398383613c1c565b600080600083850360e0811215613f61578182fd5b843567ffffffffffffffff80821115613f78578384fd5b9086019060e08289031215613f8b578384fd5b90945060208601359080821115613fa0578384fd5b50613fad87828801613cb1565b93505060a0603f1982011215613fc1578182fd5b506040840190509250925092565b60008060408385031215613fe1578182fd5b505080516020909101519092909150565b600080600080600060a08688031215614009578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b6000806000806101008587031215614047578182fd5b843560ff81168114614057578283fd5b9350602085013567ffffffffffffffff80821115614073578384fd5b61407f88838901613d86565b94506040870135915080821115614094578384fd5b506140a187828801613cb1565b9250506140b18660608701613c1c565b905092959194509250565b6001600160a01b03169052565b15159052565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b8181101561411e57602081850181015186830182015201614102565b8181111561412f5782602083870101525b50601f01601f19169290920160200192915050565b803561414f816146e8565b6001600160a01b03908116835260208201359061416b826146e8565b9081166020840152604082013590614182826146e8565b9081166040840152606082013590614199826146e8565b90811660608401526080820135906141b0826146e8565b808216608085015250505050565b60006101806141ce8484516140bc565b60208301516141e060208601826140bc565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e083015160e085015261010080840151818601525061012080840151818601525061014080840151614248828701826140c9565b5050610160808401518282870152614262838701826140f9565b9695505050505050565b60008135614279816146e8565b6001600160a01b039081168452602083013590614295826146e8565b808216602086015260408401356040860152606084013560608601526080840135608086015260a084013591506142cb826146e8565b1660a084015260c082013536839003601e190181126142e8578182fd5b8201803567ffffffffffffffff811115614300578283fd5b80360384131561430e578283fd5b60e060c086015261432660e0860182602085016140cf565b95945050505050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03868116825260208201869052604082018590528316606082015260a0608082018190526000906139fd908301846140f9565b90815260200190565b9182526001600160a01b0316602082015260400190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614262908301846140f9565b600061010060ff871683528060208401526144448184018761426c565b9050828103604084015261445881866141be565b9150506143266060830184614144565b600060a0825261447b60a08301886140f9565b90508560208301528460408301528360608301528260808301529695505050505050565b60208082526028908201527f4d5041202f20436f756c64206e6f7420617070726f76652045786368616e676560408201526720666f722044414960c01b606082015260800190565b60208082526015908201527418d85b9b9bdd081c995c185e48185b1b081919589d605a1b604082015260600190565b60208082526022908201527f63616e6e6f7420636c6f736520746f2044414920696620464c206e6f74207573604082015261195960f21b606082015260800190565b6020808252602a908201527f4d5041202f20436f756c64206e6f7420617070726f76652045786368616e6765604082015269103337b9102a37b5b2b760b11b606082015260800190565b6020808252600f908201526e696e743235362d6f766572666c6f7760881b604082015260600190565b60208082526025908201527f6d70612d726563656976652d7265717565737465642d616d6f756e742d6d69736040820152640dac2e8c6d60db1b606082015260800190565b60208082526014908201527336b83096bab73a393ab9ba32b216b632b73232b960611b604082015260600190565b6020808252601f908201527f7468697320636f64652073686f756c6420626520756e726561636861626c6500604082015260600190565b9283526001600160a01b03919091166020830152604082015260600190565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff811182821017156146d457fe5b604052919050565b600061113c3683613d86565b6001600160a01b03811681146146fd57600080fd5b50565b80151581146146fd57600080fdfe64656372656173654d756c7469706c655769746864726177436f6c6c61746572616cead01ff65532b6ee1646408ed4a14f45b5ee091a71e9bb1f579c0a44d59230110000000000000000000000006b175474e89094c44da98b954eedeac495271d0f696e6372656173654d756c7469706c654465706f736974436f6c6c61746572616c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220f80eb6141e0e7d3fc2e5d49a3dfc5c4f794a82b855b832a91ca49631f8197a7a64736f6c63430007060033

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.