Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
13481555 | 1191 days ago | 9.94636977 ETH | ||||
13481555 | 1191 days ago | 9.94636977 ETH | ||||
13480312 | 1191 days ago | 260.39959997 ETH | ||||
13480312 | 1191 days ago | 260.39959997 ETH | ||||
13470617 | 1193 days ago | 140.76898501 ETH | ||||
13470617 | 1193 days ago | 140.76898501 ETH | ||||
13467445 | 1193 days ago | 4.3457782 ETH | ||||
13467445 | 1193 days ago | 4.3457782 ETH | ||||
13462924 | 1194 days ago | 56.03181928 ETH | ||||
13462924 | 1194 days ago | 56.03181928 ETH | ||||
13462488 | 1194 days ago | 108.95505754 ETH | ||||
13462488 | 1194 days ago | 108.95505754 ETH | ||||
13461612 | 1194 days ago | 10.59470758 ETH | ||||
13461612 | 1194 days ago | 10.59470758 ETH | ||||
13461299 | 1194 days ago | 412.12199094 ETH | ||||
13461299 | 1194 days ago | 412.12199094 ETH | ||||
13460832 | 1194 days ago | 403.84863053 ETH | ||||
13460832 | 1194 days ago | 403.84863053 ETH | ||||
13455393 | 1195 days ago | 5.21462203 ETH | ||||
13455393 | 1195 days ago | 5.21462203 ETH | ||||
13452913 | 1196 days ago | 226.52079385 ETH | ||||
13452913 | 1196 days ago | 226.52079385 ETH | ||||
13441233 | 1197 days ago | 4.43854135 ETH | ||||
13441233 | 1197 days ago | 4.43854135 ETH | ||||
13441173 | 1197 days ago | 34.34779018 ETH |
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
Contract Source Code (Solidity Standard Json-Input format)
// 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 "../interfaces/aaveV2/ILendingPoolAddressesProviderV2.sol"; import "../interfaces/aaveV2/ILendingPoolV2.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"; 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 aaveLendingPoolProvider; 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 { using SafeMath for uint256; uint256 constant RAY = 10**27; address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address public constant DAIJOIN = 0x9759A6Ac90977b93B58547b4A71c78317f391A28; uint16 constant AAVE_REFERRAL = 197; modifier logMethodName( string memory name, CdpData memory data, address destination ) { if (bytes(data.methodName).length == 0) { data.methodName = name; } _; data.methodName = ""; } function getAaveLendingPool(address lendingPoolProvider) private view returns (ILendingPoolV2) { ILendingPoolAddressesProviderV2 provider = ILendingPoolAddressesProviderV2(lendingPoolProvider); ILendingPoolV2 lendingPool = ILendingPoolV2(provider.getLendingPool()); return lendingPool; } function takeAFlashLoan( AddressRegistry memory addressRegistry, CdpData memory cdpData, address[] memory assets, uint256[] memory amounts, uint256[] memory modes, bytes memory paramsData ) internal { IManager(addressRegistry.manager).cdpAllow( cdpData.cdpId, addressRegistry.multiplyProxyActions, 1 ); ILendingPoolV2 lendingPool = getAaveLendingPool(addressRegistry.aaveLendingPoolProvider); lendingPool.flashLoan( addressRegistry.multiplyProxyActions, assets, amounts, modes, address(this), paramsData, AAVE_REFERRAL ); 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(); address[] memory assets = new address[](1); assets[0] = DAI; uint256[] memory amounts = new uint256[](1); amounts[0] = cdpData.requiredDebt; uint256[] memory modes = new uint256[](1); modes[0] = 0; 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, assets, amounts, modes, 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(); address[] memory assets = new address[](1); assets[0] = DAI; uint256[] memory amounts = new uint256[](1); amounts[0] = cdpData.requiredDebt; uint256[] memory modes = new uint256[](1); modes[0] = 0; bytes memory paramsData = abi.encode(0, exchangeData, cdpData, addressRegistry); if (cdpData.skipFL) { _decreaseMP(exchangeData, cdpData, addressRegistry, 0); } else { takeAFlashLoan(addressRegistry, cdpData, assets, amounts, modes, 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; address[] memory assets = new address[](1); assets[0] = DAI; uint256[] memory amounts = new uint256[](1); amounts[0] = wadD; uint256[] memory modes = new uint256[](1); modes[0] = 0; bytes memory paramsData = abi.encode(mode, exchangeData, cdpData, addressRegistry); if (cdpData.skipFL == false) { takeAFlashLoan(addressRegistry, cdpData, assets, amounts, modes, 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 executeOperation( address[] calldata assets, uint256[] calldata amounts, uint256[] calldata premiums, address initiator, bytes calldata params ) external returns (bool) { ( uint8 mode, ExchangeData memory exchangeData, CdpData memory cdpData, AddressRegistry memory addressRegistry ) = abi.decode(params, (uint8, ExchangeData, CdpData, AddressRegistry)); uint256 borrowedDaiAmount = amounts[0].add(premiums[0]); emit FLData(IERC20(DAI).balanceOf(address(this)).sub(cdpData.depositDai), borrowedDaiAmount); uint256 ink = getInk(addressRegistry.manager, cdpData); require( cdpData.requiredDebt.add(cdpData.depositDai) <= IERC20(DAI).balanceOf(address(this)), "requested and received amounts mismatch" ); if (mode == 0) { _decreaseMP(exchangeData, cdpData, addressRegistry, premiums[0]); } if (mode == 1) { _increaseMP(exchangeData, cdpData, addressRegistry, premiums[0]); } if (mode == 2) { _closeWithdrawCollateral(exchangeData, cdpData, addressRegistry, borrowedDaiAmount, cdpData.borrowCollateral); } if (mode == 3) { _closeWithdrawDai(exchangeData, cdpData, addressRegistry, borrowedDaiAmount, cdpData.borrowCollateral); } IERC20(assets[0]).approve( address(getAaveLendingPool(addressRegistry.aaveLendingPoolProvider)), borrowedDaiAmount ); return true; } 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: agpl-3.0 pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; /** * @title LendingPoolAddressesProvider contract * @dev Main registry of addresses part of or connected to the protocol, including permissioned roles * - Acting also as factory of proxies and admin of those, so with right to change its implementations * - Owned by the Aave Governance * @author Aave **/ interface ILendingPoolAddressesProviderV2 { event LendingPoolUpdated(address indexed newAddress); event ConfigurationAdminUpdated(address indexed newAddress); event EmergencyAdminUpdated(address indexed newAddress); event LendingPoolConfiguratorUpdated(address indexed newAddress); event LendingPoolCollateralManagerUpdated(address indexed newAddress); event PriceOracleUpdated(address indexed newAddress); event LendingRateOracleUpdated(address indexed newAddress); event ProxyCreated(bytes32 id, address indexed newAddress); event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy); function setAddress(bytes32 id, address newAddress) external; function setAddressAsProxy(bytes32 id, address impl) external; function getAddress(bytes32 id) external view returns (address); function getLendingPool() external view returns (address); function setLendingPoolImpl(address pool) external; function getLendingPoolConfigurator() external view returns (address); function setLendingPoolConfiguratorImpl(address configurator) external; function getLendingPoolCollateralManager() external view returns (address); function setLendingPoolCollateralManager(address manager) external; function getPoolAdmin() external view returns (address); function setPoolAdmin(address admin) external; function getEmergencyAdmin() external view returns (address); function setEmergencyAdmin(address admin) external; function getPriceOracle() external view returns (address); function setPriceOracle(address priceOracle) external; function getLendingRateOracle() external view returns (address); function setLendingRateOracle(address lendingRateOracle) external; }
// SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; import './ILendingPoolAddressesProviderV2.sol'; library DataTypes { // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. struct ReserveData { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; //the current stable borrow rate. Expressed in ray uint128 currentStableBorrowRate; uint40 lastUpdateTimestamp; //tokens addresses address aTokenAddress; address stableDebtTokenAddress; address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the id of the reserve. Represents the position in the list of the active reserves uint8 id; } struct ReserveConfigurationMap { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus //bit 48-55: Decimals //bit 56: Reserve is active //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled //bit 60-63: reserved //bit 64-79: reserve factor uint256 data; } struct UserConfigurationMap { uint256 data; } enum InterestRateMode { NONE, STABLE, VARIABLE } } interface ILendingPoolV2 { /** * @dev Emitted on deposit() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the deposit * @param onBehalfOf The beneficiary of the deposit, receiving the aTokens * @param amount The amount deposited * @param referral The referral code used **/ event Deposit( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referral ); /** * @dev Emitted on withdraw() * @param reserve The address of the underlyng asset being withdrawn * @param user The address initiating the withdrawal, owner of aTokens * @param to Address that will receive the underlying * @param amount The amount to be withdrawn **/ event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); /** * @dev Emitted on borrow() and flashLoan() when debt needs to be opened * @param reserve The address of the underlying asset being borrowed * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just * initiator of the transaction on flashLoan() * @param onBehalfOf The address that will be getting the debt * @param amount The amount borrowed out * @param borrowRateMode The rate mode: 1 for Stable, 2 for Variable * @param borrowRate The numeric rate at which the user has borrowed * @param referral The referral code used **/ event Borrow( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint256 borrowRateMode, uint256 borrowRate, uint16 indexed referral ); /** * @dev Emitted on repay() * @param reserve The address of the underlying asset of the reserve * @param user The beneficiary of the repayment, getting his debt reduced * @param repayer The address of the user initiating the repay(), providing the funds * @param amount The amount repaid **/ event Repay( address indexed reserve, address indexed user, address indexed repayer, uint256 amount ); /** * @dev Emitted on swapBorrowRateMode() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user swapping his rate mode * @param rateMode The rate mode that the user wants to swap to **/ event Swap(address indexed reserve, address indexed user, uint256 rateMode); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral **/ event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral **/ event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); /** * @dev Emitted on rebalanceStableBorrowRate() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user for which the rebalance has been executed **/ event RebalanceStableBorrowRate(address indexed reserve, address indexed user); /** * @dev Emitted on flashLoan() * @param target The address of the flash loan receiver contract * @param initiator The address initiating the flash loan * @param asset The address of the asset being flash borrowed * @param amount The amount flash borrowed * @param premium The fee flash borrowed * @param referralCode The referral code used **/ event FlashLoan( address indexed target, address indexed initiator, address indexed asset, uint256 amount, uint256 premium, uint16 referralCode ); /** * @dev Emitted when the pause is triggered. */ event Paused(); /** * @dev Emitted when the pause is lifted. */ event Unpaused(); /** * @dev Emitted when a borrower is liquidated. This event is emitted by the LendingPool via * LendingPoolCollateral manager using a DELEGATECALL * This allows to have the events in the generated ABI for LendingPool. * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param liquidatedCollateralAmount The amount of collateral received by the liiquidator * @param liquidator The address of the liquidator * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly **/ event LiquidationCall( address indexed collateralAsset, address indexed debtAsset, address indexed user, uint256 debtToCover, uint256 liquidatedCollateralAmount, address liquidator, bool receiveAToken ); /** * @dev Emitted when the state of a reserve is updated. NOTE: This event is actually declared * in the ReserveLogic library and emitted in the updateInterestRates() function. Since the function is internal, * the event will actually be fired by the LendingPool contract. The event is therefore replicated here so it * gets added to the LendingPool ABI * @param reserve The address of the underlying asset of the reserve * @param liquidityRate The new liquidity rate * @param stableBorrowRate The new stable borrow rate * @param variableBorrowRate The new variable borrow rate * @param liquidityIndex The new liquidity index * @param variableBorrowIndex The new variable borrow index **/ event ReserveDataUpdated( address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex ); /** * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User deposits 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to deposit * @param amount The amount to be deposited * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man **/ function deposit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to Address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet **/ function withdraw( address asset, uint256 amount, address to ) external; /** * @dev Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower * already deposited enough collateral, or he was given enough allowance by a credit delegator on the * corresponding debt token (StableDebtToken or VariableDebtToken) * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 stable/variable debt tokens, depending on the `interestRateMode` * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param onBehalfOf Address of the user who will receive the debt. Should be the address of the borrower itself * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator * if he has been given credit delegation allowance **/ function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; /** * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed **/ function repay( address asset, uint256 amount, uint256 rateMode, address onBehalfOf ) external; /** * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa * @param asset The address of the underlying asset borrowed * @param rateMode The rate mode that the user wants to swap to **/ function swapBorrowRateMode(address asset, uint256 rateMode) external; /** * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. * - Users can be rebalanced if the following conditions are satisfied: * 1. Usage ratio is above 95% * 2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been * borrowed at a stable rate and depositors are not earning enough * @param asset The address of the underlying asset borrowed * @param user The address of the user to be rebalanced **/ function rebalanceStableBorrowRate(address asset, address user) external; /** * @dev Allows depositors to enable/disable a specific deposited asset as collateral * @param asset The address of the underlying asset deposited * @param useAsCollateral `true` if the user wants to use the deposit as collateral, `false` otherwise **/ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; /** * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly **/ function liquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; /** * @dev Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept into consideration. * For further details please visit https://developers.aave.com * @param receiverAddress The address of the contract receiving the funds, implementing the IFlashLoanReceiver interface * @param assets The addresses of the assets being flash-borrowed * @param amounts The amounts amounts being flash-borrowed * @param modes Types of the debt to open if the flash loan is not returned: * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man **/ function flashLoan( address receiverAddress, address[] calldata assets, uint256[] calldata amounts, uint256[] calldata modes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; /** * @dev Returns the user account data across all the reserves * @param user The address of the user * @return totalCollateralETH the total collateral in ETH of the user * @return totalDebtETH the total debt in ETH of the user * @return availableBorrowsETH the borrowing power left of the user * @return currentLiquidationThreshold the liquidation threshold of the user * @return ltv the loan to value of the user * @return healthFactor the current health factor of the user **/ function getUserAccountData(address user) external view returns ( uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); function initReserve( address reserve, address aTokenAddress, address stableDebtAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; function setReserveInterestRateStrategyAddress(address reserve, address rateStrategyAddress) external; function setConfiguration(address reserve, uint256 configuration) external; /** * @dev Returns the configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve **/ function getConfiguration(address asset) external view returns (DataTypes.ReserveConfigurationMap memory); /** * @dev Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user **/ function getUserConfiguration(address user) external view returns (DataTypes.UserConfigurationMap memory); /** * @dev Returns the normalized income normalized income of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve's normalized income */ function getReserveNormalizedIncome(address asset) external view returns (uint256); /** * @dev Returns the normalized variable debt per unit of asset * @param asset The address of the underlying asset of the reserve * @return The reserve normalized variable debt */ function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); /** * @dev Returns the state and configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The state of the reserve **/ function getReserveData(address asset) external view returns (DataTypes.ReserveData memory); function finalizeTransfer( address asset, address from, address to, uint256 amount, uint256 balanceFromAfter, uint256 balanceToBefore ) external; function getReservesList() external view returns (address[] memory); function getAddressesProvider() external view returns (ILendingPoolAddressesProviderV2); function setPause(bool val) external; function paused() external view returns (bool); }
// 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; }
// 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; }
// 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; }
// 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); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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":"aaveLendingPoolProvider","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":"aaveLendingPoolProvider","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":"aaveLendingPoolProvider","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":"aaveLendingPoolProvider","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":"aaveLendingPoolProvider","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"decreaseMultipleWithdrawDai","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"premiums","type":"uint256[]"},{"internalType":"address","name":"initiator","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"executeOperation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"aaveLendingPoolProvider","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":"aaveLendingPoolProvider","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":"aaveLendingPoolProvider","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"increaseMultipleDepositDai","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":"aaveLendingPoolProvider","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"internalType":"struct AddressRegistry","name":"addressRegistry","type":"tuple"}],"name":"openMultiplyVault","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50614de4806100206000396000f3fe6080604052600436106100c25760003560e01c806371ae86a51161007f578063ad5c464811610059578063ad5c4648146101ed578063cedee4ef1461020f578063e0bab4c414610222578063f85c2ce314610237576100c2565b806371ae86a514610184578063920f5c84146101a457806399e13c1a146101da576100c2565b80630521a3c7146100c45780631c9ea1e0146100e45780631f41f7b61461010457806334f67473146101245780633b9b4d95146101445780634a9b4e0c14610164575b005b3480156100d057600080fd5b506100c26100df3660046144a3565b61024c565b3480156100f057600080fd5b506100c26100ff3660046144a3565b6102b2565b34801561011057600080fd5b506100c261011f3660046144a3565b6102eb565b34801561013057600080fd5b506100c261013f3660046144a3565b610372565b34801561015057600080fd5b506100c261015f3660046144a3565b6103b8565b34801561017057600080fd5b506100c261017f3660046144a3565b61041f565b34801561019057600080fd5b506100c261019f3660046144a3565b610477565b3480156101b057600080fd5b506101c46101bf366004614357565b610615565b6040516101d19190614a24565b60405180910390f35b6100c26101e83660046144a3565b610954565b3480156101f957600080fd5b50610202610abf565b6040516101d191906148c8565b6100c261021d3660046144a3565b610ad7565b34801561022e57600080fd5b50610202610daa565b34801561024357600080fd5b50610202610dbc565b604051806060016040528060228152602001614d0b6022913982610276606084016040850161431f565b6101608201515161028a5761016082018390525b610295868686610dd4565b506040805160208101909152600081526101609091015250505050565b604080518082018252601081526f64656372656173654d756c7469706c6560801b6020820152908390610276906060850190850161431f565b6040805180820182526011815270636c6f73655661756c744578697444616960781b6020820152908390610325906060850190850161431f565b610160820151516103395761016082018390525b610140850151156103655760405162461bcd60e51b815260040161035c90614b85565b60405180910390fd5b6102958686866003610fa7565b604080518082018252601b81527f64656372656173654d756c7469706c65576974686472617744616900000000006020820152908390610276906060850190850161431f565b604080518082018252601881527f636c6f73655661756c7445786974436f6c6c61746572616c000000000000000060208201529083906103fe906060850190850161431f565b610160820151516104125761016082018390525b6102958686866002610fa7565b604080518082018252601081526f696e6372656173654d756c7469706c6560801b6020820152908390610458906060850190850161431f565b6101608201515161046c5761016082018390525b6102958686866112d6565b604080518082018252601a81527f696e6372656173654d756c7469706c654465706f73697444616900000000000060208201529083906104bd906060850190850161431f565b610160820151516104d15761016082018390525b8461014001511561056e576101008501516040516323b872dd60e01b8152600080516020614d4d833981519152916323b872dd916105169133913091906004016148f6565b602060405180830381600087803b15801561053057600080fd5b505af1158015610544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105689190614454565b5061046c565b600080516020614d4d8339815191526323b872dd33610593606088016040890161431f565b8861010001516040518463ffffffff1660e01b81526004016105b7939291906148f6565b602060405180830381600087803b1580156105d157600080fd5b505af11580156105e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106099190614454565b506102958686866112d6565b60008080808061062786880188614588565b9350935093509350600061066a8b8b600081811061064157fe5b905060200201358e8e600081811061065557fe5b905060200201356115c790919063ffffffff16565b90507f9c6641b21946115d10f3f55df9bec5752ec06d40dc9250b1cc6560549764600e610726846101000151600080516020614d4d8339815191526001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016106d091906148c8565b60206040518083038186803b1580156106e857600080fd5b505afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190614470565b9061162a565b82604051610735929190614ca6565b60405180910390a1600061074d83602001518561166c565b6040516370a0823160e01b8152909150600080516020614d4d833981519152906370a08231906107819030906004016148c8565b60206040518083038186803b15801561079957600080fd5b505afa1580156107ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d19190614470565b61010085015160808601516107e5916115c7565b11156108035760405162461bcd60e51b815260040161035c90614ac7565b60ff861661082a5761082a8585858f8f600081811061081e57fe5b905060200201356117f4565b8560ff1660011415610855576108558585858f8f600081811061084957fe5b90506020020135611bae565b8560ff166002141561087257610872858585858860a00151611e4b565b8560ff166003141561088f5761088f858585858860a001516121b1565b8f8f600081811061089c57fe5b90506020020160208101906108b1919061431f565b6001600160a01b031663095ea7b36108cc8560600151612564565b846040518363ffffffff1660e01b81526004016108ea92919061491a565b602060405180830381600087803b15801561090457600080fd5b505af1158015610918573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093c9190614454565b50600196505050505050509998505050505050505050565b60408051808201825260118152701bdc195b935d5b1d1a5c1b1e55985d5b1d607a1b602082015290839061098e906060850190850161431f565b610160820151516109a25761016082018390525b84600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a179190614470565b6060860152610a2c604085016020860161431f565b6001600160a01b0316636090dec58660600151306040518363ffffffff1660e01b8152600401610a5d929190614a38565b602060405180830381600087803b158015610a7757600080fd5b505af1158015610a8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aaf9190614470565b6040860152610295868686610ad7565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b604051806060016040528060218152602001614d6d6021913982610b01606084016040850161431f565b61016082015151610b155761016082018390525b600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5457600080fd5b505afa158015610b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8c919061433b565b90506001600160a01b03811673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415610caa57806001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610bee57600080fd5b505af1158015610c02573d6000803e3d6000fd5b5050505061014087015115159050610ca5576001600160a01b03811663a9059cbb610c33606088016040890161431f565b346040518363ffffffff1660e01b8152600401610c5192919061491a565b602060405180830381600087803b158015610c6b57600080fd5b505af1158015610c7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca39190614454565b505b610d81565b610140860151610cf8576001600160a01b0381166323b872dd33610cd46060890160408a0161431f565b8961012001516040518463ffffffff1660e01b8152600401610c51939291906148f6565b6101208601516040516323b872dd60e01b81526001600160a01b038316916323b872dd91610d2d9133913091906004016148f6565b602060405180830381600087803b158015610d4757600080fd5b505af1158015610d5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7f9190614454565b505b610d8c8787876112d6565b50506040805160208101909152600081526101609091015250505050565b600080516020614d4d83398151915281565b739759a6ac90977b93b58547b4a71c78317f391a2881565b81600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e1157600080fd5b505afa158015610e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e499190614470565b606083015260408051600180825281830190925260009160208083019080368337019050509050600080516020614d4d83398151915281600081518110610e8c57fe5b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050509050836080015181600081518110610edb57fe5b6020908102919091010152604080516001808252818301909252600091816020016020820280368337019050509050600081600081518110610f1957fe5b602002602001018181525050600080878787604051602001610f3e9493929190614a4f565b604051602081830303815290604052905085610140015115610f8257610f7d610f6688614cd8565b87610f7636899003890189614488565b60006117f4565b610f9e565b610f9e610f9436879003870187614488565b87868686866125e7565b50505050505050565b82600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610fe457600080fd5b505afa158015610ff8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101c9190614470565b60608401526000611033604084016020850161431f565b6001600160a01b0316632726b07385604001516040518263ffffffff1660e01b81526004016110629190614a2f565b60206040518083038186803b15801561107a57600080fd5b505afa15801561108e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b2919061433b565b905060006110c6604085016020860161431f565b6001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156110fe57600080fd5b505afa158015611112573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611136919061433b565b9050600061114a8284858960600151612741565b608087018190526040805160018082528183019092529192506000919060208083019080368337019050509050600080516020614d4d8339815191528160008151811061119357fe5b6001600160a01b03929092166020928302919091019091015260408051600180825281830190925260009181602001602082028036833701905050905082816000815181106111de57fe5b602090810291909101015260408051600180825281830190925260009181602001602082028036833701905050905060008160008151811061121c57fe5b6020026020010181815250506000878b8b8b6040516020016112419493929190614a4f565b60408051601f198184030181529190526101408b015190915061127f5761127a611270368b90038b018b614488565b8b868686866125e7565b6112c9565b8760ff16600214156112b15761127a6112978c614cd8565b8b6112a7368d90038d018d614488565b8d60a0015161291d565b60405162461bcd60e51b815260040161035c90614c3a565b5050505050505050505050565b81600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561131357600080fd5b505afa158015611327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134b9190614470565b606083015260408051600180825281830190925260009160208083019080368337019050509050600080516020614d4d8339815191528160008151811061138e57fe5b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092526000918160200160208202803683370190505090508360800151816000815181106113dd57fe5b602090810291909101015260408051600180825281830190925260009181602001602082028036833701905050905060008160008151811061141b57fe5b602002602001018181525050600060018787876040516020016114419493929190614a4f565b604051602081830303815290604052905085610140015115610f8257600086600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561149c57600080fd5b505afa1580156114b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d4919061433b565b90506000816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161150491906148c8565b60206040518083038186803b15801561151c57600080fd5b505afa158015611530573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115549190614470565b9050801561158e57608088015161158990899061157760408b0160208c0161431f565b61158460208c018c61431f565b612d95565b61159d565b61159d88888a60800151613238565b6115c06115a98a614cd8565b896115b9368b90038b018b614488565b6000611bae565b5050610f9e565b600082820183811015611621576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600061162183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506135e0565b600080836001600160a01b0316632726b07384604001516040518263ffffffff1660e01b815260040161169f9190614a2f565b60206040518083038186803b1580156116b757600080fd5b505afa1580156116cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ef919061433b565b90506000846001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b15801561172c57600080fd5b505afa158015611740573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611764919061433b565b90506000816001600160a01b0316632424be5c8660600151856040518363ffffffff1660e01b815260040161179a929190614a38565b604080518083038186803b1580156117b157600080fd5b505afa1580156117c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e99190614526565b509695505050505050565b608082015161014084015160009061181e5760e085015160808601516118199161162a565b611821565b60005b9050611856846020015186600001518760400151846118518a60c001518b60a001516115c790919063ffffffff16565b613677565b8551604080880151905163095ea7b360e01b81526001600160a01b039092169163095ea7b39161188b9186919060040161491a565b602060405180830381600087803b1580156118a557600080fd5b505af11580156118b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118dd9190614454565b6118f95760405162461bcd60e51b815260040161035c90614bc7565b816001600160a01b031663c723c87f87600001518860400151611929878a608001516115c790919063ffffffff16565b8a60a001518b60c001516040518663ffffffff1660e01b81526004016119539594939291906149ea565b600060405180830381600087803b15801561196d57600080fd5b505af1158015611981573d6000803e3d6000fd5b505087516040516370a0823160e01b8152600093506001600160a01b0390911691506370a08231906119b79030906004016148c8565b60206040518083038186803b1580156119cf57600080fd5b505afa1580156119e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a079190614470565b9050600086610140015115611a7457602086015187516040808a015160e08b015191516370a0823160e01b8152611a69949392611a6291600080516020614d4d833981519152906370a08231906106d09030906004016148c8565b6000613677565b5060e0860151611abb565b6080870151611ab890611a8790876115c7565b6040516370a0823160e01b8152600080516020614d4d833981519152906370a08231906106d09030906004016148c8565b90505b8660400151600080516020614d2d8339815191528861016001518a608001518b606001518686604051611af2959493929190614a90565b60405180910390a28015611b8b57602087015160405163a9059cbb60e01b8152600080516020614d4d8339815191529163a9059cbb91611b379190859060040161491a565b602060405180830381600087803b158015611b5157600080fd5b505af1158015611b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b899190614454565b505b8115611ba457611ba48760000151886020015184613ac0565b5050505050505050565b60808083015190840151600090611bc590846115c7565b905084610140015115611bd6575060005b600080516020614d4d8339815191526001600160a01b031663095ea7b383611c108861010001518a604001516115c790919063ffffffff16565b6040518363ffffffff1660e01b8152600401611c2d92919061491a565b602060405180830381600087803b158015611c4757600080fd5b505af1158015611c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7f9190614454565b611c9b5760405162461bcd60e51b815260040161035c90614b0e565b816001600160a01b031663bc6f02b28760200151611ccb8861010001518a604001516115c790919063ffffffff16565b89608001518a60a001518b60c001516040518663ffffffff1660e01b8152600401611cfa9594939291906149ea565b600060405180830381600087803b158015611d1457600080fd5b505af1158015611d28573d6000803e3d6000fd5b50505050611d40858286602001518760000151612d95565b6040516370a0823160e01b8152600090611d7a908390600080516020614d4d833981519152906370a08231906106d09030906004016148c8565b90508560400151600080516020614d2d83398151915287610160015189608001518a60600151600086604051611db4959493929190614a90565b60405180910390a28015610f9e57602086015160405163a9059cbb60e01b8152600080516020614d4d8339815191529163a9059cbb91611df99190859060040161491a565b602060405180830381600087803b158015611e1357600080fd5b505af1158015611e27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba49190614454565b600083608001519050600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015611e9357600080fd5b505afa158015611ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecb919061433b565b9050611eea856020015187600001518860400151896080015187613677565b865160405163095ea7b360e01b81526001600160a01b039091169063095ea7b390611f1b908590879060040161491a565b602060405180830381600087803b158015611f3557600080fd5b505af1158015611f49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6d9190614454565b611f895760405162461bcd60e51b815260040161035c90614bc7565b865160408089015160808a015160a08b015160c08c0151935163c723c87f60e01b81526001600160a01b0388169563c723c87f95611fcf959194919391926004016149ea565b600060405180830381600087803b158015611fe957600080fd5b505af1158015611ffd573d6000803e3d6000fd5b50506040516370a0823160e01b81526000925061203b91508690600080516020614d4d833981519152906370a08231906106d09030906004016148c8565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161206b91906148c8565b60206040518083038186803b15801561208357600080fd5b505afa158015612097573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120bb9190614470565b9050811561214e57602088015160405163a9059cbb60e01b8152600080516020614d4d8339815191529163a9059cbb916120fa9190869060040161491a565b602060405180830381600087803b15801561211457600080fd5b505af1158015612128573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214c9190614454565b505b8015612167576121678860000151896020015183613ac0565b8760400151600080516020614d2d8339815191528961016001518b608001518c60600151858760405161219e959493929190614a90565b60405180910390a2505050505050505050565b600083608001519050600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b1580156121f957600080fd5b505afa15801561220d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612231919061433b565b9050612250856020015187600001518860400151896080015187613677565b86600001516001600160a01b031663095ea7b383836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161229091906148c8565b60206040518083038186803b1580156122a857600080fd5b505afa1580156122bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e09190614470565b6040518363ffffffff1660e01b81526004016122fd92919061491a565b602060405180830381600087803b15801561231757600080fd5b505af115801561232b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234f9190614454565b61236b5760405162461bcd60e51b815260040161035c90614bc7565b8651608088015160a089015160c08a015160405163c723c87f60e01b81526001600160a01b0387169463c723c87f946123ad9491938a939192916004016149ea565b600060405180830381600087803b1580156123c757600080fd5b505af11580156123db573d6000803e3d6000fd5b50506040516370a0823160e01b81526000925061241991508690600080516020614d4d833981519152906370a08231906106d09030906004016148c8565b905080156124ac57602087015160405163a9059cbb60e01b8152600080516020614d4d8339815191529163a9059cbb916124589190859060040161491a565b602060405180830381600087803b15801561247257600080fd5b505af1158015612486573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124aa9190614454565b505b6040516370a0823160e01b81526000906001600160a01b038416906370a08231906124db9030906004016148c8565b60206040518083038186803b1580156124f357600080fd5b505afa158015612507573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061252b9190614470565b90508760400151600080516020614d2d8339815191528961016001518b608001518c60600151858760405161219e959493929190614a90565b6000808290506000816001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125a557600080fd5b505afa1580156125b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125dd919061433b565b925050505b919050565b85602001516001600160a01b0316630b63fb628660400151886040015160016040518463ffffffff1660e01b815260040161262493929190614c71565b600060405180830381600087803b15801561263e57600080fd5b505af1158015612652573d6000803e3d6000fd5b5050505060006126658760600151612564565b604080890151905163ab9c4b5d60e01b81529192506001600160a01b0383169163ab9c4b5d916126a49189908990899030908a9060c590600401614933565b600060405180830381600087803b1580156126be57600080fd5b505af11580156126d2573d6000803e3d6000fd5b5050505086602001516001600160a01b0316630b63fb628760400151896040015160006040518463ffffffff1660e01b815260040161271393929190614c71565b600060405180830381600087803b15801561272d57600080fd5b505af11580156112c9573d6000803e3d6000fd5b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b81526004016127709190614a2f565b60a06040518083038186803b15801561278857600080fd5b505afa15801561279c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127c09190614549565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b81526004016127f6929190614a38565b604080518083038186803b15801561280d57600080fd5b505afa158015612821573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128459190614526565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b815260040161287691906148c8565b60206040518083038186803b15801561288e57600080fd5b505afa1580156128a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c69190614470565b905060006128d8826107208587613c7c565b9050676765c793fa10079d601b1b810494508061290086676765c793fa10079d601b1b613c7c565b1061290b5784612910565b846001015b9998505050505050505050565b600082608001519050600084600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561296557600080fd5b505afa158015612979573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299d919061433b565b90506129bd84602001518660000151876040015160008a60400151613677565b855160405163095ea7b360e01b81526001600160a01b039091169063095ea7b3906129ee908590879060040161491a565b602060405180830381600087803b158015612a0857600080fd5b505af1158015612a1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a409190614454565b612a5c5760405162461bcd60e51b815260040161035c90614bc7565b8551604080880151608089015160a08a015160c08b0151935163c723c87f60e01b81526001600160a01b0388169563c723c87f95612aa2959194919391926004016149ea565b600060405180830381600087803b158015612abc57600080fd5b505af1158015612ad0573d6000803e3d6000fd5b50506040516370a0823160e01b815260009250600080516020614d4d83398151915291506370a0823190612b089030906004016148c8565b60206040518083038186803b158015612b2057600080fd5b505afa158015612b34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b589190614470565b90508086608001511115612b7e5760405162461bcd60e51b815260040161035c90614b56565b612b9f85602001518760000151886040015189608001518a60c00151613677565b6040516370a0823160e01b8152600080516020614d4d833981519152906370a0823190612bd09030906004016148c8565b60206040518083038186803b158015612be857600080fd5b505afa158015612bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c209190614470565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401612c5091906148c8565b60206040518083038186803b158015612c6857600080fd5b505afa158015612c7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ca09190614470565b90508115612d3357602087015160405163a9059cbb60e01b8152600080516020614d4d8339815191529163a9059cbb91612cdf9190869060040161491a565b602060405180830381600087803b158015612cf957600080fd5b505af1158015612d0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d319190614454565b505b8015612d4c57612d4c8760000151886020015183613ac0565b8660400151600080516020614d2d8339815191528861016001518a608001518b606001518587604051612d83959493929190614a90565b60405180910390a25050505050505050565b600084600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015612dd457600080fd5b505afa158015612de8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0c919061433b565b90506000816001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401612e3c91906148c8565b60206040518083038186803b158015612e5457600080fd5b505afa158015612e68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e8c9190614470565b865160405163095ea7b360e01b81529192506001600160a01b0384169163095ea7b391612ebd91859060040161491a565b600060405180830381600087803b158015612ed757600080fd5b505af1158015612eeb573d6000803e3d6000fd5b505050506000846001600160a01b0316632726b07388604001516040518263ffffffff1660e01b8152600401612f219190614a2f565b60206040518083038186803b158015612f3957600080fd5b505afa158015612f4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f71919061433b565b90506000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015612fae57600080fd5b505afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe6919061433b565b8851604051633b4da69f60e01b81529192506001600160a01b031690633b4da69f90613018908590879060040161491a565b600060405180830381600087803b15801561303257600080fd5b505af1158015613046573d6000803e3d6000fd5b50505050856001600160a01b03166345e6bdcd896040015161307461306f8c6000015188613cd5565b613d58565b613085858a888f606001518f613d7a565b6040518463ffffffff1660e01b81526004016130a393929190614c90565b600060405180830381600087803b1580156130bd57600080fd5b505af11580156130d1573d6000803e3d6000fd5b50505060408901516001600160a01b038816915063f9f30db690306131018b676765c793fa10079d601b1b613c7c565b6040518463ffffffff1660e01b815260040161311f93929190614c71565b600060405180830381600087803b15801561313957600080fd5b505af115801561314d573d6000803e3d6000fd5b50506040516328ec8bf160e21b81526001600160a01b038416925063a3b22fc4915061319190739759a6ac90977b93b58547b4a71c78317f391a28906004016148c8565b600060405180830381600087803b1580156131ab57600080fd5b505af11580156131bf573d6000803e3d6000fd5b505060405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a28925063ef693bed91506131fc9030908b9060040161491a565b600060405180830381600087803b15801561321657600080fd5b505af115801561322a573d6000803e3d6000fd5b505050505050505050505050565b600061324a604084016020850161431f565b6001600160a01b0316632726b07385604001516040518263ffffffff1660e01b81526004016132799190614a2f565b60206040518083038186803b15801561329157600080fd5b505afa1580156132a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c9919061433b565b905060006132dd604085016020860161431f565b6001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b15801561331557600080fd5b505afa158015613329573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061334d919061433b565b905061335f604085016020860161431f565b6001600160a01b03166345e6bdcd866040015160006133978589600001602081019061338b919061431f565b888c606001518b613d7a565b6040518463ffffffff1660e01b81526004016133b593929190614c90565b600060405180830381600087803b1580156133cf57600080fd5b505af11580156133e3573d6000803e3d6000fd5b506133f892505050604085016020860161431f565b6001600160a01b031663f9f30db686604001513061341587613f02565b6040518463ffffffff1660e01b815260040161343393929190614c71565b600060405180830381600087803b15801561344d57600080fd5b505af1158015613461573d6000803e3d6000fd5b5050604051634538c4eb60e01b81526001600160a01b0384169250634538c4eb91506134a7903090739759a6ac90977b93b58547b4a71c78317f391a28906004016148dc565b60206040518083038186803b1580156134bf57600080fd5b505afa1580156134d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f79190614470565b61356e576040516328ec8bf160e21b81526001600160a01b0382169063a3b22fc49061353b90739759a6ac90977b93b58547b4a71c78317f391a28906004016148c8565b600060405180830381600087803b15801561355557600080fd5b505af1158015613569573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed906135a7903090879060040161491a565b600060405180830381600087803b1580156135c157600080fd5b505af11580156135d5573d6000803e3d6000fd5b505050505050505050565b6000818484111561366f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561363457818101518382015260200161361c565b50505050905090810190601f1680156136615780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156136b257600080fd5b505afa1580156136c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136ea919061433b565b90506000866001600160a01b0316632726b073866040518263ffffffff1660e01b815260040161371a9190614a2f565b60206040518083038186803b15801561373257600080fd5b505afa158015613746573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061376a919061433b565b90506000876001600160a01b0316632c2cb9fd876040518263ffffffff1660e01b815260040161379a9190614a2f565b60206040518083038186803b1580156137b257600080fd5b505afa1580156137c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ea9190614470565b60405163095ea7b360e01b8152909150600080516020614d4d8339815191529063095ea7b39061383490739759a6ac90977b93b58547b4a71c78317f391a2890899060040161491a565b602060405180830381600087803b15801561384e57600080fd5b505af1158015613862573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138869190614454565b50604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f906138c0908590899060040161491a565b600060405180830381600087803b1580156138da57600080fd5b505af11580156138ee573d6000803e3d6000fd5b5050505060006138fe8886613cd5565b9050886001600160a01b03166345e6bdcd8861391984613d58565b6000036139a388896001600160a01b0316636c25b3468a6040518263ffffffff1660e01b815260040161394c91906148c8565b60206040518083038186803b15801561396457600080fd5b505afa158015613978573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061399c9190614470565b8989613f19565b6040518463ffffffff1660e01b81526004016139c193929190614c90565b600060405180830381600087803b1580156139db57600080fd5b505af11580156139ef573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b038c169250639bb8f8389150613a23908a9030908690600401614c71565b600060405180830381600087803b158015613a3d57600080fd5b505af1158015613a51573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038b16925063ef693bed9150613a83903090899060040161491a565b600060405180830381600087803b158015613a9d57600080fd5b505af1158015613ab1573d6000803e3d6000fd5b50505050505050505050505050565b6000836001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015613afb57600080fd5b505afa158015613b0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b33919061433b565b90506001600160a01b03811673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415613bf457604051632e1a7d4d60e01b81526001600160a01b03821690632e1a7d4d90613b86908590600401614a2f565b600060405180830381600087803b158015613ba057600080fd5b505af1158015613bb4573d6000803e3d6000fd5b50506040516001600160a01b038616925084156108fc02915084906000818181858888f19350505050158015613bee573d6000803e3d6000fd5b50613c76565b60405163a9059cbb60e01b81526001600160a01b0382169063a9059cbb90613c22908690869060040161491a565b602060405180830381600087803b158015613c3c57600080fd5b505af1158015613c50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c749190614454565b505b50505050565b600082613c8b57506000611624565b82820282848281613c9857fe5b04146116215760405162461bcd60e51b8152600401808060200182810382526021815260200180614d8e6021913960400191505060405180910390fd5b6000611621836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b158015613d1357600080fd5b505afa158015613d27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d4b9190614470565b8390601203600a0a613c7c565b8060008112156125e25760405162461bcd60e51b815260040161035c90614c11565b600080856001600160a01b03166344e2a5a8856040518263ffffffff1660e01b8152600401613da99190614a2f565b602060405180830381600087803b158015613dc357600080fd5b505af1158015613dd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dfb9190614470565b90506000876001600160a01b0316636c25b346876040518263ffffffff1660e01b8152600401613e2b91906148c8565b60206040518083038186803b158015613e4357600080fd5b505afa158015613e57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e7b9190614470565b9050613e9284676765c793fa10079d601b1b613c7c565b811015613ef757613ec382613eb68361072088676765c793fa10079d601b1b613c7c565b81613ebd57fe5b04613d58565b9250613eda84676765c793fa10079d601b1b613c7c565b613ee48484613c7c565b10613eef5782613ef4565b826001015b92505b505095945050505050565b600061162482676765c793fa10079d601b1b613c7c565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b8152600401613f489190614a2f565b60a06040518083038186803b158015613f6057600080fd5b505afa158015613f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f989190614549565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b8152600401613fce929190614a38565b604080518083038186803b158015613fe557600080fd5b505afa158015613ff9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061401d9190614526565b91505061402c828781613ebd57fe5b9250808311156140475761403f81613d58565b60000361404c565b826000035b979650505050505050565b80356125e281614ce4565b60008083601f840112614073578182fd5b50813567ffffffffffffffff81111561408a578182fd5b60208301915083602080830285010111156140a457600080fd5b9250929050565b80356125e281614cfc565b600082601f8301126140c6578081fd5b813567ffffffffffffffff8111156140da57fe5b6140ed601f8201601f1916602001614cb4565b818152846020838601011115614101578283fd5b816020850160208301379081016020019190915292915050565b600060a0828403121561412c578081fd5b60405160a0810181811067ffffffffffffffff8211171561414957fe5b604052905080823561415a81614ce4565b8152602083013561416a81614ce4565b6020820152604083013561417d81614ce4565b6040820152606083013561419081614ce4565b606082015260808301356141a381614ce4565b6080919091015292915050565b60006101808083850312156141c3578182fd5b6141cc81614cb4565b9150506141d882614057565b81526141e660208301614057565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a082015260c082013560c082015260e082013560e082015261010080830135818301525061012080830135818301525061014061424d8184016140ab565b908201526101608281013567ffffffffffffffff81111561426d57600080fd5b614279858286016140b6565b82840152505092915050565b600060e08284031215614296578081fd5b6142a060e0614cb4565b90506142ab82614057565b81526142b960208301614057565b60208201526040820135604082015260608201356060820152608082013560808201526142e860a08301614057565b60a082015260c082013567ffffffffffffffff81111561430757600080fd5b614313848285016140b6565b60c08301525092915050565b600060208284031215614330578081fd5b813561162181614ce4565b60006020828403121561434c578081fd5b815161162181614ce4565b600080600080600080600080600060a08a8c031215614374578485fd5b893567ffffffffffffffff8082111561438b578687fd5b6143978d838e01614062565b909b50995060208c01359150808211156143af578687fd5b6143bb8d838e01614062565b909950975060408c01359150808211156143d3578687fd5b6143df8d838e01614062565b909750955060608c013591506143f482614ce4565b90935060808b01359080821115614409578384fd5b818c0191508c601f83011261441c578384fd5b81358181111561442a578485fd5b8d602082850101111561443b578485fd5b6020830194508093505050509295985092959850929598565b600060208284031215614465578081fd5b815161162181614cfc565b600060208284031215614481578081fd5b5051919050565b600060a08284031215614499578081fd5b611621838361411b565b600080600083850360e08112156144b8578182fd5b843567ffffffffffffffff808211156144cf578384fd5b9086019060e082890312156144e2578384fd5b909450602086013590808211156144f7578384fd5b50614504878288016141b0565b93505060a0603f1982011215614518578182fd5b506040840190509250925092565b60008060408385031215614538578182fd5b505080516020909101519092909150565b600080600080600060a08688031215614560578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b600080600080610100858703121561459e578182fd5b843560ff811681146145ae578283fd5b9350602085013567ffffffffffffffff808211156145ca578384fd5b6145d688838901614285565b945060408701359150808211156145eb578384fd5b506145f8878288016141b0565b925050614608866060870161411b565b905092959194509250565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101561464f57815187529582019590820190600101614633565b509495945050505050565b15159052565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b818110156146af57602081850181015186830182015201614693565b818111156146c05782602083870101525b50601f01601f19169290920160200192915050565b80356146e081614ce4565b6001600160a01b0390811683526020820135906146fc82614ce4565b908116602084015260408201359061471382614ce4565b908116604084015260608201359061472a82614ce4565b908116606084015260808201359061474182614ce4565b808216608085015250505050565b600061018061475f848451614613565b60208301516147716020860182614613565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e083015160e0850152610100808401518186015250610120808401518186015250610140808401516147d98287018261465a565b50506101608084015182828701526147f38387018261468a565b9695505050505050565b6000813561480a81614ce4565b6001600160a01b03908116845260208301359061482682614ce4565b808216602086015260408401356040860152606084013560608601526080840135608086015260a0840135915061485c82614ce4565b1660a084015260c082013536839003601e19018112614879578182fd5b8201803567ffffffffffffffff811115614891578283fd5b80360384131561489f578283fd5b60e060c08601526148b760e086018260208501614660565b95945050505050565b61ffff169052565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03888116825260e0602080840182905289519184018290526000928a820192909190610100860190855b81811015614982578551851683529483019491830191600101614964565b50508581036040870152614996818c614620565b935050505082810360608401526149ad8188614620565b90506149bc6080840187614613565b82810360a08401526149ce818661468a565b9150506149de60c08301846148c0565b98975050505050505050565b6001600160a01b03868116825260208201869052604082018590528316606082015260a06080820181905260009061404c9083018461468a565b901515815260200190565b90815260200190565b9182526001600160a01b0316602082015260400190565b600061010060ff87168352806020840152614a6c818401876147fd565b90508281036040840152614a80818661474f565b9150506148b760608301846146d5565b600060a08252614aa360a083018861468a565b90508560208301528460408301528360608301528260808301529695505050505050565b60208082526027908201527f72657175657374656420616e6420726563656976656420616d6f756e7473206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526028908201527f4d5041202f20436f756c64206e6f7420617070726f76652045786368616e676560408201526720666f722044414960c01b606082015260800190565b60208082526015908201527418d85b9b9bdd081c995c185e48185b1b081919589d605a1b604082015260600190565b60208082526022908201527f63616e6e6f7420636c6f736520746f2044414920696620464c206e6f74207573604082015261195960f21b606082015260800190565b6020808252602a908201527f4d5041202f20436f756c64206e6f7420617070726f76652045786368616e6765604082015269103337b9102a37b5b2b760b11b606082015260800190565b6020808252600f908201526e696e743235362d6f766572666c6f7760881b604082015260600190565b6020808252601f908201527f7468697320636f64652073686f756c6420626520756e726561636861626c6500604082015260600190565b9283526001600160a01b03919091166020830152604082015260600190565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715614cd057fe5b604052919050565b60006116243683614285565b6001600160a01b0381168114614cf957600080fd5b50565b8015158114614cf957600080fdfe64656372656173654d756c7469706c655769746864726177436f6c6c61746572616cead01ff65532b6ee1646408ed4a14f45b5ee091a71e9bb1f579c0a44d59230110000000000000000000000006b175474e89094c44da98b954eedeac495271d0f696e6372656173654d756c7469706c654465706f736974436f6c6c61746572616c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a264697066735822122043c674d2f9b87a5365d247d033b6aecbd68243d064a152b0450ec7d88fb624cd64736f6c63430007060033
Deployed Bytecode
0x6080604052600436106100c25760003560e01c806371ae86a51161007f578063ad5c464811610059578063ad5c4648146101ed578063cedee4ef1461020f578063e0bab4c414610222578063f85c2ce314610237576100c2565b806371ae86a514610184578063920f5c84146101a457806399e13c1a146101da576100c2565b80630521a3c7146100c45780631c9ea1e0146100e45780631f41f7b61461010457806334f67473146101245780633b9b4d95146101445780634a9b4e0c14610164575b005b3480156100d057600080fd5b506100c26100df3660046144a3565b61024c565b3480156100f057600080fd5b506100c26100ff3660046144a3565b6102b2565b34801561011057600080fd5b506100c261011f3660046144a3565b6102eb565b34801561013057600080fd5b506100c261013f3660046144a3565b610372565b34801561015057600080fd5b506100c261015f3660046144a3565b6103b8565b34801561017057600080fd5b506100c261017f3660046144a3565b61041f565b34801561019057600080fd5b506100c261019f3660046144a3565b610477565b3480156101b057600080fd5b506101c46101bf366004614357565b610615565b6040516101d19190614a24565b60405180910390f35b6100c26101e83660046144a3565b610954565b3480156101f957600080fd5b50610202610abf565b6040516101d191906148c8565b6100c261021d3660046144a3565b610ad7565b34801561022e57600080fd5b50610202610daa565b34801561024357600080fd5b50610202610dbc565b604051806060016040528060228152602001614d0b6022913982610276606084016040850161431f565b6101608201515161028a5761016082018390525b610295868686610dd4565b506040805160208101909152600081526101609091015250505050565b604080518082018252601081526f64656372656173654d756c7469706c6560801b6020820152908390610276906060850190850161431f565b6040805180820182526011815270636c6f73655661756c744578697444616960781b6020820152908390610325906060850190850161431f565b610160820151516103395761016082018390525b610140850151156103655760405162461bcd60e51b815260040161035c90614b85565b60405180910390fd5b6102958686866003610fa7565b604080518082018252601b81527f64656372656173654d756c7469706c65576974686472617744616900000000006020820152908390610276906060850190850161431f565b604080518082018252601881527f636c6f73655661756c7445786974436f6c6c61746572616c000000000000000060208201529083906103fe906060850190850161431f565b610160820151516104125761016082018390525b6102958686866002610fa7565b604080518082018252601081526f696e6372656173654d756c7469706c6560801b6020820152908390610458906060850190850161431f565b6101608201515161046c5761016082018390525b6102958686866112d6565b604080518082018252601a81527f696e6372656173654d756c7469706c654465706f73697444616900000000000060208201529083906104bd906060850190850161431f565b610160820151516104d15761016082018390525b8461014001511561056e576101008501516040516323b872dd60e01b8152600080516020614d4d833981519152916323b872dd916105169133913091906004016148f6565b602060405180830381600087803b15801561053057600080fd5b505af1158015610544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105689190614454565b5061046c565b600080516020614d4d8339815191526323b872dd33610593606088016040890161431f565b8861010001516040518463ffffffff1660e01b81526004016105b7939291906148f6565b602060405180830381600087803b1580156105d157600080fd5b505af11580156105e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106099190614454565b506102958686866112d6565b60008080808061062786880188614588565b9350935093509350600061066a8b8b600081811061064157fe5b905060200201358e8e600081811061065557fe5b905060200201356115c790919063ffffffff16565b90507f9c6641b21946115d10f3f55df9bec5752ec06d40dc9250b1cc6560549764600e610726846101000151600080516020614d4d8339815191526001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016106d091906148c8565b60206040518083038186803b1580156106e857600080fd5b505afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190614470565b9061162a565b82604051610735929190614ca6565b60405180910390a1600061074d83602001518561166c565b6040516370a0823160e01b8152909150600080516020614d4d833981519152906370a08231906107819030906004016148c8565b60206040518083038186803b15801561079957600080fd5b505afa1580156107ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d19190614470565b61010085015160808601516107e5916115c7565b11156108035760405162461bcd60e51b815260040161035c90614ac7565b60ff861661082a5761082a8585858f8f600081811061081e57fe5b905060200201356117f4565b8560ff1660011415610855576108558585858f8f600081811061084957fe5b90506020020135611bae565b8560ff166002141561087257610872858585858860a00151611e4b565b8560ff166003141561088f5761088f858585858860a001516121b1565b8f8f600081811061089c57fe5b90506020020160208101906108b1919061431f565b6001600160a01b031663095ea7b36108cc8560600151612564565b846040518363ffffffff1660e01b81526004016108ea92919061491a565b602060405180830381600087803b15801561090457600080fd5b505af1158015610918573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093c9190614454565b50600196505050505050509998505050505050505050565b60408051808201825260118152701bdc195b935d5b1d1a5c1b1e55985d5b1d607a1b602082015290839061098e906060850190850161431f565b610160820151516109a25761016082018390525b84600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a179190614470565b6060860152610a2c604085016020860161431f565b6001600160a01b0316636090dec58660600151306040518363ffffffff1660e01b8152600401610a5d929190614a38565b602060405180830381600087803b158015610a7757600080fd5b505af1158015610a8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aaf9190614470565b6040860152610295868686610ad7565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b604051806060016040528060218152602001614d6d6021913982610b01606084016040850161431f565b61016082015151610b155761016082018390525b600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5457600080fd5b505afa158015610b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8c919061433b565b90506001600160a01b03811673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415610caa57806001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610bee57600080fd5b505af1158015610c02573d6000803e3d6000fd5b5050505061014087015115159050610ca5576001600160a01b03811663a9059cbb610c33606088016040890161431f565b346040518363ffffffff1660e01b8152600401610c5192919061491a565b602060405180830381600087803b158015610c6b57600080fd5b505af1158015610c7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca39190614454565b505b610d81565b610140860151610cf8576001600160a01b0381166323b872dd33610cd46060890160408a0161431f565b8961012001516040518463ffffffff1660e01b8152600401610c51939291906148f6565b6101208601516040516323b872dd60e01b81526001600160a01b038316916323b872dd91610d2d9133913091906004016148f6565b602060405180830381600087803b158015610d4757600080fd5b505af1158015610d5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7f9190614454565b505b610d8c8787876112d6565b50506040805160208101909152600081526101609091015250505050565b600080516020614d4d83398151915281565b739759a6ac90977b93b58547b4a71c78317f391a2881565b81600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e1157600080fd5b505afa158015610e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e499190614470565b606083015260408051600180825281830190925260009160208083019080368337019050509050600080516020614d4d83398151915281600081518110610e8c57fe5b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050509050836080015181600081518110610edb57fe5b6020908102919091010152604080516001808252818301909252600091816020016020820280368337019050509050600081600081518110610f1957fe5b602002602001018181525050600080878787604051602001610f3e9493929190614a4f565b604051602081830303815290604052905085610140015115610f8257610f7d610f6688614cd8565b87610f7636899003890189614488565b60006117f4565b610f9e565b610f9e610f9436879003870187614488565b87868686866125e7565b50505050505050565b82600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610fe457600080fd5b505afa158015610ff8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101c9190614470565b60608401526000611033604084016020850161431f565b6001600160a01b0316632726b07385604001516040518263ffffffff1660e01b81526004016110629190614a2f565b60206040518083038186803b15801561107a57600080fd5b505afa15801561108e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b2919061433b565b905060006110c6604085016020860161431f565b6001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156110fe57600080fd5b505afa158015611112573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611136919061433b565b9050600061114a8284858960600151612741565b608087018190526040805160018082528183019092529192506000919060208083019080368337019050509050600080516020614d4d8339815191528160008151811061119357fe5b6001600160a01b03929092166020928302919091019091015260408051600180825281830190925260009181602001602082028036833701905050905082816000815181106111de57fe5b602090810291909101015260408051600180825281830190925260009181602001602082028036833701905050905060008160008151811061121c57fe5b6020026020010181815250506000878b8b8b6040516020016112419493929190614a4f565b60408051601f198184030181529190526101408b015190915061127f5761127a611270368b90038b018b614488565b8b868686866125e7565b6112c9565b8760ff16600214156112b15761127a6112978c614cd8565b8b6112a7368d90038d018d614488565b8d60a0015161291d565b60405162461bcd60e51b815260040161035c90614c3a565b5050505050505050505050565b81600001516001600160a01b031663c5ce281e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561131357600080fd5b505afa158015611327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134b9190614470565b606083015260408051600180825281830190925260009160208083019080368337019050509050600080516020614d4d8339815191528160008151811061138e57fe5b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092526000918160200160208202803683370190505090508360800151816000815181106113dd57fe5b602090810291909101015260408051600180825281830190925260009181602001602082028036833701905050905060008160008151811061141b57fe5b602002602001018181525050600060018787876040516020016114419493929190614a4f565b604051602081830303815290604052905085610140015115610f8257600086600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561149c57600080fd5b505afa1580156114b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d4919061433b565b90506000816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161150491906148c8565b60206040518083038186803b15801561151c57600080fd5b505afa158015611530573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115549190614470565b9050801561158e57608088015161158990899061157760408b0160208c0161431f565b61158460208c018c61431f565b612d95565b61159d565b61159d88888a60800151613238565b6115c06115a98a614cd8565b896115b9368b90038b018b614488565b6000611bae565b5050610f9e565b600082820183811015611621576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600061162183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506135e0565b600080836001600160a01b0316632726b07384604001516040518263ffffffff1660e01b815260040161169f9190614a2f565b60206040518083038186803b1580156116b757600080fd5b505afa1580156116cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ef919061433b565b90506000846001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b15801561172c57600080fd5b505afa158015611740573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611764919061433b565b90506000816001600160a01b0316632424be5c8660600151856040518363ffffffff1660e01b815260040161179a929190614a38565b604080518083038186803b1580156117b157600080fd5b505afa1580156117c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e99190614526565b509695505050505050565b608082015161014084015160009061181e5760e085015160808601516118199161162a565b611821565b60005b9050611856846020015186600001518760400151846118518a60c001518b60a001516115c790919063ffffffff16565b613677565b8551604080880151905163095ea7b360e01b81526001600160a01b039092169163095ea7b39161188b9186919060040161491a565b602060405180830381600087803b1580156118a557600080fd5b505af11580156118b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118dd9190614454565b6118f95760405162461bcd60e51b815260040161035c90614bc7565b816001600160a01b031663c723c87f87600001518860400151611929878a608001516115c790919063ffffffff16565b8a60a001518b60c001516040518663ffffffff1660e01b81526004016119539594939291906149ea565b600060405180830381600087803b15801561196d57600080fd5b505af1158015611981573d6000803e3d6000fd5b505087516040516370a0823160e01b8152600093506001600160a01b0390911691506370a08231906119b79030906004016148c8565b60206040518083038186803b1580156119cf57600080fd5b505afa1580156119e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a079190614470565b9050600086610140015115611a7457602086015187516040808a015160e08b015191516370a0823160e01b8152611a69949392611a6291600080516020614d4d833981519152906370a08231906106d09030906004016148c8565b6000613677565b5060e0860151611abb565b6080870151611ab890611a8790876115c7565b6040516370a0823160e01b8152600080516020614d4d833981519152906370a08231906106d09030906004016148c8565b90505b8660400151600080516020614d2d8339815191528861016001518a608001518b606001518686604051611af2959493929190614a90565b60405180910390a28015611b8b57602087015160405163a9059cbb60e01b8152600080516020614d4d8339815191529163a9059cbb91611b379190859060040161491a565b602060405180830381600087803b158015611b5157600080fd5b505af1158015611b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b899190614454565b505b8115611ba457611ba48760000151886020015184613ac0565b5050505050505050565b60808083015190840151600090611bc590846115c7565b905084610140015115611bd6575060005b600080516020614d4d8339815191526001600160a01b031663095ea7b383611c108861010001518a604001516115c790919063ffffffff16565b6040518363ffffffff1660e01b8152600401611c2d92919061491a565b602060405180830381600087803b158015611c4757600080fd5b505af1158015611c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7f9190614454565b611c9b5760405162461bcd60e51b815260040161035c90614b0e565b816001600160a01b031663bc6f02b28760200151611ccb8861010001518a604001516115c790919063ffffffff16565b89608001518a60a001518b60c001516040518663ffffffff1660e01b8152600401611cfa9594939291906149ea565b600060405180830381600087803b158015611d1457600080fd5b505af1158015611d28573d6000803e3d6000fd5b50505050611d40858286602001518760000151612d95565b6040516370a0823160e01b8152600090611d7a908390600080516020614d4d833981519152906370a08231906106d09030906004016148c8565b90508560400151600080516020614d2d83398151915287610160015189608001518a60600151600086604051611db4959493929190614a90565b60405180910390a28015610f9e57602086015160405163a9059cbb60e01b8152600080516020614d4d8339815191529163a9059cbb91611df99190859060040161491a565b602060405180830381600087803b158015611e1357600080fd5b505af1158015611e27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba49190614454565b600083608001519050600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015611e9357600080fd5b505afa158015611ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecb919061433b565b9050611eea856020015187600001518860400151896080015187613677565b865160405163095ea7b360e01b81526001600160a01b039091169063095ea7b390611f1b908590879060040161491a565b602060405180830381600087803b158015611f3557600080fd5b505af1158015611f49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6d9190614454565b611f895760405162461bcd60e51b815260040161035c90614bc7565b865160408089015160808a015160a08b015160c08c0151935163c723c87f60e01b81526001600160a01b0388169563c723c87f95611fcf959194919391926004016149ea565b600060405180830381600087803b158015611fe957600080fd5b505af1158015611ffd573d6000803e3d6000fd5b50506040516370a0823160e01b81526000925061203b91508690600080516020614d4d833981519152906370a08231906106d09030906004016148c8565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161206b91906148c8565b60206040518083038186803b15801561208357600080fd5b505afa158015612097573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120bb9190614470565b9050811561214e57602088015160405163a9059cbb60e01b8152600080516020614d4d8339815191529163a9059cbb916120fa9190869060040161491a565b602060405180830381600087803b15801561211457600080fd5b505af1158015612128573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214c9190614454565b505b8015612167576121678860000151896020015183613ac0565b8760400151600080516020614d2d8339815191528961016001518b608001518c60600151858760405161219e959493929190614a90565b60405180910390a2505050505050505050565b600083608001519050600085600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b1580156121f957600080fd5b505afa15801561220d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612231919061433b565b9050612250856020015187600001518860400151896080015187613677565b86600001516001600160a01b031663095ea7b383836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161229091906148c8565b60206040518083038186803b1580156122a857600080fd5b505afa1580156122bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e09190614470565b6040518363ffffffff1660e01b81526004016122fd92919061491a565b602060405180830381600087803b15801561231757600080fd5b505af115801561232b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234f9190614454565b61236b5760405162461bcd60e51b815260040161035c90614bc7565b8651608088015160a089015160c08a015160405163c723c87f60e01b81526001600160a01b0387169463c723c87f946123ad9491938a939192916004016149ea565b600060405180830381600087803b1580156123c757600080fd5b505af11580156123db573d6000803e3d6000fd5b50506040516370a0823160e01b81526000925061241991508690600080516020614d4d833981519152906370a08231906106d09030906004016148c8565b905080156124ac57602087015160405163a9059cbb60e01b8152600080516020614d4d8339815191529163a9059cbb916124589190859060040161491a565b602060405180830381600087803b15801561247257600080fd5b505af1158015612486573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124aa9190614454565b505b6040516370a0823160e01b81526000906001600160a01b038416906370a08231906124db9030906004016148c8565b60206040518083038186803b1580156124f357600080fd5b505afa158015612507573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061252b9190614470565b90508760400151600080516020614d2d8339815191528961016001518b608001518c60600151858760405161219e959493929190614a90565b6000808290506000816001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125a557600080fd5b505afa1580156125b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125dd919061433b565b925050505b919050565b85602001516001600160a01b0316630b63fb628660400151886040015160016040518463ffffffff1660e01b815260040161262493929190614c71565b600060405180830381600087803b15801561263e57600080fd5b505af1158015612652573d6000803e3d6000fd5b5050505060006126658760600151612564565b604080890151905163ab9c4b5d60e01b81529192506001600160a01b0383169163ab9c4b5d916126a49189908990899030908a9060c590600401614933565b600060405180830381600087803b1580156126be57600080fd5b505af11580156126d2573d6000803e3d6000fd5b5050505086602001516001600160a01b0316630b63fb628760400151896040015160006040518463ffffffff1660e01b815260040161271393929190614c71565b600060405180830381600087803b15801561272d57600080fd5b505af11580156112c9573d6000803e3d6000fd5b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b81526004016127709190614a2f565b60a06040518083038186803b15801561278857600080fd5b505afa15801561279c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127c09190614549565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b81526004016127f6929190614a38565b604080518083038186803b15801561280d57600080fd5b505afa158015612821573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128459190614526565b9150506000876001600160a01b0316636c25b346886040518263ffffffff1660e01b815260040161287691906148c8565b60206040518083038186803b15801561288e57600080fd5b505afa1580156128a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c69190614470565b905060006128d8826107208587613c7c565b9050676765c793fa10079d601b1b810494508061290086676765c793fa10079d601b1b613c7c565b1061290b5784612910565b846001015b9998505050505050505050565b600082608001519050600084600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b15801561296557600080fd5b505afa158015612979573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299d919061433b565b90506129bd84602001518660000151876040015160008a60400151613677565b855160405163095ea7b360e01b81526001600160a01b039091169063095ea7b3906129ee908590879060040161491a565b602060405180830381600087803b158015612a0857600080fd5b505af1158015612a1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a409190614454565b612a5c5760405162461bcd60e51b815260040161035c90614bc7565b8551604080880151608089015160a08a015160c08b0151935163c723c87f60e01b81526001600160a01b0388169563c723c87f95612aa2959194919391926004016149ea565b600060405180830381600087803b158015612abc57600080fd5b505af1158015612ad0573d6000803e3d6000fd5b50506040516370a0823160e01b815260009250600080516020614d4d83398151915291506370a0823190612b089030906004016148c8565b60206040518083038186803b158015612b2057600080fd5b505afa158015612b34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b589190614470565b90508086608001511115612b7e5760405162461bcd60e51b815260040161035c90614b56565b612b9f85602001518760000151886040015189608001518a60c00151613677565b6040516370a0823160e01b8152600080516020614d4d833981519152906370a0823190612bd09030906004016148c8565b60206040518083038186803b158015612be857600080fd5b505afa158015612bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c209190614470565b90506000826001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401612c5091906148c8565b60206040518083038186803b158015612c6857600080fd5b505afa158015612c7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ca09190614470565b90508115612d3357602087015160405163a9059cbb60e01b8152600080516020614d4d8339815191529163a9059cbb91612cdf9190869060040161491a565b602060405180830381600087803b158015612cf957600080fd5b505af1158015612d0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d319190614454565b505b8015612d4c57612d4c8760000151886020015183613ac0565b8660400151600080516020614d2d8339815191528861016001518a608001518b606001518587604051612d83959493929190614a90565b60405180910390a25050505050505050565b600084600001516001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015612dd457600080fd5b505afa158015612de8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0c919061433b565b90506000816001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401612e3c91906148c8565b60206040518083038186803b158015612e5457600080fd5b505afa158015612e68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e8c9190614470565b865160405163095ea7b360e01b81529192506001600160a01b0384169163095ea7b391612ebd91859060040161491a565b600060405180830381600087803b158015612ed757600080fd5b505af1158015612eeb573d6000803e3d6000fd5b505050506000846001600160a01b0316632726b07388604001516040518263ffffffff1660e01b8152600401612f219190614a2f565b60206040518083038186803b158015612f3957600080fd5b505afa158015612f4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f71919061433b565b90506000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b158015612fae57600080fd5b505afa158015612fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe6919061433b565b8851604051633b4da69f60e01b81529192506001600160a01b031690633b4da69f90613018908590879060040161491a565b600060405180830381600087803b15801561303257600080fd5b505af1158015613046573d6000803e3d6000fd5b50505050856001600160a01b03166345e6bdcd896040015161307461306f8c6000015188613cd5565b613d58565b613085858a888f606001518f613d7a565b6040518463ffffffff1660e01b81526004016130a393929190614c90565b600060405180830381600087803b1580156130bd57600080fd5b505af11580156130d1573d6000803e3d6000fd5b50505060408901516001600160a01b038816915063f9f30db690306131018b676765c793fa10079d601b1b613c7c565b6040518463ffffffff1660e01b815260040161311f93929190614c71565b600060405180830381600087803b15801561313957600080fd5b505af115801561314d573d6000803e3d6000fd5b50506040516328ec8bf160e21b81526001600160a01b038416925063a3b22fc4915061319190739759a6ac90977b93b58547b4a71c78317f391a28906004016148c8565b600060405180830381600087803b1580156131ab57600080fd5b505af11580156131bf573d6000803e3d6000fd5b505060405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a28925063ef693bed91506131fc9030908b9060040161491a565b600060405180830381600087803b15801561321657600080fd5b505af115801561322a573d6000803e3d6000fd5b505050505050505050505050565b600061324a604084016020850161431f565b6001600160a01b0316632726b07385604001516040518263ffffffff1660e01b81526004016132799190614a2f565b60206040518083038186803b15801561329157600080fd5b505afa1580156132a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c9919061433b565b905060006132dd604085016020860161431f565b6001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b15801561331557600080fd5b505afa158015613329573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061334d919061433b565b905061335f604085016020860161431f565b6001600160a01b03166345e6bdcd866040015160006133978589600001602081019061338b919061431f565b888c606001518b613d7a565b6040518463ffffffff1660e01b81526004016133b593929190614c90565b600060405180830381600087803b1580156133cf57600080fd5b505af11580156133e3573d6000803e3d6000fd5b506133f892505050604085016020860161431f565b6001600160a01b031663f9f30db686604001513061341587613f02565b6040518463ffffffff1660e01b815260040161343393929190614c71565b600060405180830381600087803b15801561344d57600080fd5b505af1158015613461573d6000803e3d6000fd5b5050604051634538c4eb60e01b81526001600160a01b0384169250634538c4eb91506134a7903090739759a6ac90977b93b58547b4a71c78317f391a28906004016148dc565b60206040518083038186803b1580156134bf57600080fd5b505afa1580156134d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f79190614470565b61356e576040516328ec8bf160e21b81526001600160a01b0382169063a3b22fc49061353b90739759a6ac90977b93b58547b4a71c78317f391a28906004016148c8565b600060405180830381600087803b15801561355557600080fd5b505af1158015613569573d6000803e3d6000fd5b505050505b60405163ef693bed60e01b8152739759a6ac90977b93b58547b4a71c78317f391a289063ef693bed906135a7903090879060040161491a565b600060405180830381600087803b1580156135c157600080fd5b505af11580156135d5573d6000803e3d6000fd5b505050505050505050565b6000818484111561366f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561363457818101518382015260200161361c565b50505050905090810190601f1680156136615780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000856001600160a01b03166336569e776040518163ffffffff1660e01b815260040160206040518083038186803b1580156136b257600080fd5b505afa1580156136c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136ea919061433b565b90506000866001600160a01b0316632726b073866040518263ffffffff1660e01b815260040161371a9190614a2f565b60206040518083038186803b15801561373257600080fd5b505afa158015613746573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061376a919061433b565b90506000876001600160a01b0316632c2cb9fd876040518263ffffffff1660e01b815260040161379a9190614a2f565b60206040518083038186803b1580156137b257600080fd5b505afa1580156137c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ea9190614470565b60405163095ea7b360e01b8152909150600080516020614d4d8339815191529063095ea7b39061383490739759a6ac90977b93b58547b4a71c78317f391a2890899060040161491a565b602060405180830381600087803b15801561384e57600080fd5b505af1158015613862573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138869190614454565b50604051633b4da69f60e01b8152739759a6ac90977b93b58547b4a71c78317f391a2890633b4da69f906138c0908590899060040161491a565b600060405180830381600087803b1580156138da57600080fd5b505af11580156138ee573d6000803e3d6000fd5b5050505060006138fe8886613cd5565b9050886001600160a01b03166345e6bdcd8861391984613d58565b6000036139a388896001600160a01b0316636c25b3468a6040518263ffffffff1660e01b815260040161394c91906148c8565b60206040518083038186803b15801561396457600080fd5b505afa158015613978573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061399c9190614470565b8989613f19565b6040518463ffffffff1660e01b81526004016139c193929190614c90565b600060405180830381600087803b1580156139db57600080fd5b505af11580156139ef573d6000803e3d6000fd5b50506040516313771f0760e31b81526001600160a01b038c169250639bb8f8389150613a23908a9030908690600401614c71565b600060405180830381600087803b158015613a3d57600080fd5b505af1158015613a51573d6000803e3d6000fd5b505060405163ef693bed60e01b81526001600160a01b038b16925063ef693bed9150613a83903090899060040161491a565b600060405180830381600087803b158015613a9d57600080fd5b505af1158015613ab1573d6000803e3d6000fd5b50505050505050505050505050565b6000836001600160a01b0316637bd2bea76040518163ffffffff1660e01b815260040160206040518083038186803b158015613afb57600080fd5b505afa158015613b0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b33919061433b565b90506001600160a01b03811673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415613bf457604051632e1a7d4d60e01b81526001600160a01b03821690632e1a7d4d90613b86908590600401614a2f565b600060405180830381600087803b158015613ba057600080fd5b505af1158015613bb4573d6000803e3d6000fd5b50506040516001600160a01b038616925084156108fc02915084906000818181858888f19350505050158015613bee573d6000803e3d6000fd5b50613c76565b60405163a9059cbb60e01b81526001600160a01b0382169063a9059cbb90613c22908690869060040161491a565b602060405180830381600087803b158015613c3c57600080fd5b505af1158015613c50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c749190614454565b505b50505050565b600082613c8b57506000611624565b82820282848281613c9857fe5b04146116215760405162461bcd60e51b8152600401808060200182810382526021815260200180614d8e6021913960400191505060405180910390fd5b6000611621836001600160a01b031663b3bcfa826040518163ffffffff1660e01b815260040160206040518083038186803b158015613d1357600080fd5b505afa158015613d27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d4b9190614470565b8390601203600a0a613c7c565b8060008112156125e25760405162461bcd60e51b815260040161035c90614c11565b600080856001600160a01b03166344e2a5a8856040518263ffffffff1660e01b8152600401613da99190614a2f565b602060405180830381600087803b158015613dc357600080fd5b505af1158015613dd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dfb9190614470565b90506000876001600160a01b0316636c25b346876040518263ffffffff1660e01b8152600401613e2b91906148c8565b60206040518083038186803b158015613e4357600080fd5b505afa158015613e57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e7b9190614470565b9050613e9284676765c793fa10079d601b1b613c7c565b811015613ef757613ec382613eb68361072088676765c793fa10079d601b1b613c7c565b81613ebd57fe5b04613d58565b9250613eda84676765c793fa10079d601b1b613c7c565b613ee48484613c7c565b10613eef5782613ef4565b826001015b92505b505095945050505050565b600061162482676765c793fa10079d601b1b613c7c565b600080856001600160a01b031663d9638d36846040518263ffffffff1660e01b8152600401613f489190614a2f565b60a06040518083038186803b158015613f6057600080fd5b505afa158015613f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f989190614549565b5050509150506000866001600160a01b0316632424be5c85876040518363ffffffff1660e01b8152600401613fce929190614a38565b604080518083038186803b158015613fe557600080fd5b505afa158015613ff9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061401d9190614526565b91505061402c828781613ebd57fe5b9250808311156140475761403f81613d58565b60000361404c565b826000035b979650505050505050565b80356125e281614ce4565b60008083601f840112614073578182fd5b50813567ffffffffffffffff81111561408a578182fd5b60208301915083602080830285010111156140a457600080fd5b9250929050565b80356125e281614cfc565b600082601f8301126140c6578081fd5b813567ffffffffffffffff8111156140da57fe5b6140ed601f8201601f1916602001614cb4565b818152846020838601011115614101578283fd5b816020850160208301379081016020019190915292915050565b600060a0828403121561412c578081fd5b60405160a0810181811067ffffffffffffffff8211171561414957fe5b604052905080823561415a81614ce4565b8152602083013561416a81614ce4565b6020820152604083013561417d81614ce4565b6040820152606083013561419081614ce4565b606082015260808301356141a381614ce4565b6080919091015292915050565b60006101808083850312156141c3578182fd5b6141cc81614cb4565b9150506141d882614057565b81526141e660208301614057565b602082015260408201356040820152606082013560608201526080820135608082015260a082013560a082015260c082013560c082015260e082013560e082015261010080830135818301525061012080830135818301525061014061424d8184016140ab565b908201526101608281013567ffffffffffffffff81111561426d57600080fd5b614279858286016140b6565b82840152505092915050565b600060e08284031215614296578081fd5b6142a060e0614cb4565b90506142ab82614057565b81526142b960208301614057565b60208201526040820135604082015260608201356060820152608082013560808201526142e860a08301614057565b60a082015260c082013567ffffffffffffffff81111561430757600080fd5b614313848285016140b6565b60c08301525092915050565b600060208284031215614330578081fd5b813561162181614ce4565b60006020828403121561434c578081fd5b815161162181614ce4565b600080600080600080600080600060a08a8c031215614374578485fd5b893567ffffffffffffffff8082111561438b578687fd5b6143978d838e01614062565b909b50995060208c01359150808211156143af578687fd5b6143bb8d838e01614062565b909950975060408c01359150808211156143d3578687fd5b6143df8d838e01614062565b909750955060608c013591506143f482614ce4565b90935060808b01359080821115614409578384fd5b818c0191508c601f83011261441c578384fd5b81358181111561442a578485fd5b8d602082850101111561443b578485fd5b6020830194508093505050509295985092959850929598565b600060208284031215614465578081fd5b815161162181614cfc565b600060208284031215614481578081fd5b5051919050565b600060a08284031215614499578081fd5b611621838361411b565b600080600083850360e08112156144b8578182fd5b843567ffffffffffffffff808211156144cf578384fd5b9086019060e082890312156144e2578384fd5b909450602086013590808211156144f7578384fd5b50614504878288016141b0565b93505060a0603f1982011215614518578182fd5b506040840190509250925092565b60008060408385031215614538578182fd5b505080516020909101519092909150565b600080600080600060a08688031215614560578283fd5b5050835160208501516040860151606087015160809097015192989197509594509092509050565b600080600080610100858703121561459e578182fd5b843560ff811681146145ae578283fd5b9350602085013567ffffffffffffffff808211156145ca578384fd5b6145d688838901614285565b945060408701359150808211156145eb578384fd5b506145f8878288016141b0565b925050614608866060870161411b565b905092959194509250565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101561464f57815187529582019590820190600101614633565b509495945050505050565b15159052565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b818110156146af57602081850181015186830182015201614693565b818111156146c05782602083870101525b50601f01601f19169290920160200192915050565b80356146e081614ce4565b6001600160a01b0390811683526020820135906146fc82614ce4565b908116602084015260408201359061471382614ce4565b908116604084015260608201359061472a82614ce4565b908116606084015260808201359061474182614ce4565b808216608085015250505050565b600061018061475f848451614613565b60208301516147716020860182614613565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e083015160e0850152610100808401518186015250610120808401518186015250610140808401516147d98287018261465a565b50506101608084015182828701526147f38387018261468a565b9695505050505050565b6000813561480a81614ce4565b6001600160a01b03908116845260208301359061482682614ce4565b808216602086015260408401356040860152606084013560608601526080840135608086015260a0840135915061485c82614ce4565b1660a084015260c082013536839003601e19018112614879578182fd5b8201803567ffffffffffffffff811115614891578283fd5b80360384131561489f578283fd5b60e060c08601526148b760e086018260208501614660565b95945050505050565b61ffff169052565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03888116825260e0602080840182905289519184018290526000928a820192909190610100860190855b81811015614982578551851683529483019491830191600101614964565b50508581036040870152614996818c614620565b935050505082810360608401526149ad8188614620565b90506149bc6080840187614613565b82810360a08401526149ce818661468a565b9150506149de60c08301846148c0565b98975050505050505050565b6001600160a01b03868116825260208201869052604082018590528316606082015260a06080820181905260009061404c9083018461468a565b901515815260200190565b90815260200190565b9182526001600160a01b0316602082015260400190565b600061010060ff87168352806020840152614a6c818401876147fd565b90508281036040840152614a80818661474f565b9150506148b760608301846146d5565b600060a08252614aa360a083018861468a565b90508560208301528460408301528360608301528260808301529695505050505050565b60208082526027908201527f72657175657374656420616e6420726563656976656420616d6f756e7473206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526028908201527f4d5041202f20436f756c64206e6f7420617070726f76652045786368616e676560408201526720666f722044414960c01b606082015260800190565b60208082526015908201527418d85b9b9bdd081c995c185e48185b1b081919589d605a1b604082015260600190565b60208082526022908201527f63616e6e6f7420636c6f736520746f2044414920696620464c206e6f74207573604082015261195960f21b606082015260800190565b6020808252602a908201527f4d5041202f20436f756c64206e6f7420617070726f76652045786368616e6765604082015269103337b9102a37b5b2b760b11b606082015260800190565b6020808252600f908201526e696e743235362d6f766572666c6f7760881b604082015260600190565b6020808252601f908201527f7468697320636f64652073686f756c6420626520756e726561636861626c6500604082015260600190565b9283526001600160a01b03919091166020830152604082015260600190565b9283526020830191909152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715614cd057fe5b604052919050565b60006116243683614285565b6001600160a01b0381168114614cf957600080fd5b50565b8015158114614cf957600080fdfe64656372656173654d756c7469706c655769746864726177436f6c6c61746572616cead01ff65532b6ee1646408ed4a14f45b5ee091a71e9bb1f579c0a44d59230110000000000000000000000006b175474e89094c44da98b954eedeac495271d0f696e6372656173654d756c7469706c654465706f736974436f6c6c61746572616c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a264697066735822122043c674d2f9b87a5365d247d033b6aecbd68243d064a152b0450ec7d88fb624cd64736f6c63430007060033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.