Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
18184589 | 462 days ago | 6.01991817 ETH | ||||
18184589 | 462 days ago | 6.01450512 ETH | ||||
18184589 | 462 days ago | 0.00541305 ETH | ||||
17972931 | 492 days ago | 15.87207345 ETH | ||||
17972931 | 492 days ago | 15.85780143 ETH | ||||
17972931 | 492 days ago | 0.01427202 ETH | ||||
17937365 | 497 days ago | 18.55761805 ETH | ||||
17937365 | 497 days ago | 18.54093121 ETH | ||||
17937365 | 497 days ago | 0.01668683 ETH | ||||
17937057 | 497 days ago | 27.97412634 ETH | ||||
17937057 | 497 days ago | 27.94897226 ETH | ||||
17937057 | 497 days ago | 0.02515407 ETH | ||||
17935463 | 497 days ago | 6.58469999 ETH | ||||
17935463 | 497 days ago | 6.57877909 ETH | ||||
17935463 | 497 days ago | 0.0059209 ETH | ||||
17935116 | 497 days ago | 18.88457252 ETH | ||||
17935116 | 497 days ago | 18.86759169 ETH | ||||
17935116 | 497 days ago | 0.01698083 ETH | ||||
17864165 | 507 days ago | 18.98037217 ETH | ||||
17864165 | 507 days ago | 18.9633052 ETH | ||||
17864165 | 507 days ago | 0.01706697 ETH | ||||
17806591 | 515 days ago | 40.32749634 ETH | ||||
17806591 | 515 days ago | 0.03761576 ETH | ||||
17806591 | 515 days ago | 40.3651121 ETH | ||||
17799311 | 516 days ago | 29.99315921 ETH |
Loading...
Loading
Contract Name:
AaveSaverReceiverOV2
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-09-20 */ pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; interface ERC20 { 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); } library Address { function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } 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; } } library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(ERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. */ function safeApprove(ERC20 token, address spender, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(ERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(ERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function _callOptionalReturn(ERC20 token, bytes memory data) private { bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } abstract contract TokenInterface { address public constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; 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 virtual payable; function withdraw(uint256) public virtual; } abstract contract DSAuthority { function canCall(address src, address dst, bytes4 sig) public virtual view returns (bool); } contract DSAuthEvents { event LogSetAuthority(address indexed authority); event LogSetOwner(address indexed owner); } contract DSAuth is DSAuthEvents { DSAuthority public authority; address public owner; constructor() public { owner = msg.sender; emit LogSetOwner(msg.sender); } function setOwner(address owner_) public auth { owner = owner_; emit LogSetOwner(owner); } function setAuthority(DSAuthority authority_) public auth { authority = authority_; emit LogSetAuthority(address(authority)); } modifier auth { require(isAuthorized(msg.sender, msg.sig)); _; } function isAuthorized(address src, bytes4 sig) internal view returns (bool) { if (src == address(this)) { return true; } else if (src == owner) { return true; } else if (authority == DSAuthority(0)) { return false; } else { return authority.canCall(src, address(this), sig); } } } contract DSNote { event LogNote( bytes4 indexed sig, address indexed guy, bytes32 indexed foo, bytes32 indexed bar, uint256 wad, bytes fax ) anonymous; modifier note { bytes32 foo; bytes32 bar; assembly { foo := calldataload(4) bar := calldataload(36) } emit LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data); _; } } abstract contract DSProxy is DSAuth, DSNote { DSProxyCache public cache; // global cache for contracts constructor(address _cacheAddr) public { require(setCache(_cacheAddr)); } // solhint-disable-next-line no-empty-blocks receive() external payable {} // use the proxy to execute calldata _data on contract _code // function execute(bytes memory _code, bytes memory _data) // public // payable // virtual // returns (address target, bytes32 response); function execute(address _target, bytes memory _data) public payable virtual returns (bytes32 response); //set new cache function setCache(address _cacheAddr) public virtual payable returns (bool); } contract DSProxyCache { mapping(bytes32 => address) cache; function read(bytes memory _code) public view returns (address) { bytes32 hash = keccak256(_code); return cache[hash]; } function write(bytes memory _code) public returns (address target) { assembly { target := create(0, add(_code, 0x20), mload(_code)) switch iszero(extcodesize(target)) case 1 { // throw if contract failed to deploy revert(0, 0) } } bytes32 hash = keccak256(_code); cache[hash] = target; } } contract DSMath { function add(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x + y) >= x); } function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x - y) <= x); } function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { require(y == 0 || (z = x * y) / y == x); } function div(uint256 x, uint256 y) internal pure returns (uint256 z) { return x / y; } function min(uint256 x, uint256 y) internal pure returns (uint256 z) { return x <= y ? x : y; } function max(uint256 x, uint256 y) internal pure returns (uint256 z) { return x >= y ? x : y; } function imin(int256 x, int256 y) internal pure returns (int256 z) { return x <= y ? x : y; } function imax(int256 x, int256 y) internal pure returns (int256 z) { return x >= y ? x : y; } uint256 constant WAD = 10**18; uint256 constant RAY = 10**27; function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, y), WAD / 2) / WAD; } function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, y), RAY / 2) / RAY; } function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, WAD), y / 2) / y; } function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, RAY), y / 2) / y; } // This famous algorithm is called "exponentiation by squaring" // and calculates x^n with x as fixed-point and n as regular unsigned. // // It's O(log n), instead of O(n) for naive repeated multiplication. // // These facts are why it works: // // If n is even, then x^n = (x^2)^(n/2). // If n is odd, then x^n = x * x^(n-1), // and applying the equation for even x gives // x^n = x * (x^2)^((n-1) / 2). // // Also, EVM division is flooring and // floor[(n-1) / 2] = floor[n / 2]. // function rpow(uint256 x, uint256 n) internal pure returns (uint256 z) { z = n % 2 != 0 ? x : RAY; for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } } contract Discount { address public owner; mapping(address => CustomServiceFee) public serviceFees; uint256 constant MAX_SERVICE_FEE = 400; struct CustomServiceFee { bool active; uint256 amount; } constructor() public { owner = msg.sender; } function isCustomFeeSet(address _user) public view returns (bool) { return serviceFees[_user].active; } function getCustomServiceFee(address _user) public view returns (uint256) { return serviceFees[_user].amount; } function setServiceFee(address _user, uint256 _fee) public { require(msg.sender == owner, "Only owner"); require(_fee >= MAX_SERVICE_FEE || _fee == 0); serviceFees[_user] = CustomServiceFee({active: true, amount: _fee}); } function disableServiceFee(address _user) public { require(msg.sender == owner, "Only owner"); serviceFees[_user] = CustomServiceFee({active: false, amount: 0}); } } abstract contract IFeeRecipient { function getFeeAddr() public view virtual returns (address); function changeWalletAddr(address _newWallet) public virtual; } abstract contract IAToken { function redeem(uint256 _amount) external virtual; function balanceOf(address _owner) external virtual view returns (uint256 balance); } /** * @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; } 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); } /************ @title IPriceOracleGetterAave interface @notice Interface for the Aave price oracle.*/ abstract contract IPriceOracleGetterAave { function getAssetPrice(address _asset) external virtual view returns (uint256); function getAssetsPrices(address[] calldata _assets) external virtual view returns(uint256[] memory); function getSourceOfAsset(address _asset) external virtual view returns(address); function getFallbackOracle() external virtual view returns(address); } abstract contract IAaveProtocolDataProviderV2 { struct TokenData { string symbol; address tokenAddress; } function getAllReservesTokens() external virtual view returns (TokenData[] memory); function getAllATokens() external virtual view returns (TokenData[] memory); function getReserveConfigurationData(address asset) external virtual view returns ( uint256 decimals, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, uint256 reserveFactor, bool usageAsCollateralEnabled, bool borrowingEnabled, bool stableBorrowRateEnabled, bool isActive, bool isFrozen ); function getReserveData(address asset) external virtual view returns ( uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp ); function getUserReserveData(address asset, address user) external virtual view returns ( uint256 currentATokenBalance, uint256 currentStableDebt, uint256 currentVariableDebt, uint256 principalStableDebt, uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled ); function getReserveTokensAddresses(address asset) external virtual view returns ( address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress ); } contract AdminAuth { using SafeERC20 for ERC20; address public owner; address public admin; modifier onlyOwner() { require(owner == msg.sender); _; } modifier onlyAdmin() { require(admin == msg.sender); _; } constructor() public { owner = 0xBc841B0dE0b93205e912CFBBd1D0c160A1ec6F00; admin = 0x25eFA336886C74eA8E282ac466BdCd0199f85BB9; } /// @notice Admin is set by owner first time, after that admin is super role and has permission to change owner /// @param _admin Address of multisig that becomes admin function setAdminByOwner(address _admin) public { require(msg.sender == owner); require(admin == address(0)); admin = _admin; } /// @notice Admin is able to set new admin /// @param _admin Address of multisig that becomes new admin function setAdminByAdmin(address _admin) public { require(msg.sender == admin); admin = _admin; } /// @notice Admin is able to change owner /// @param _owner Address of new owner function setOwnerByAdmin(address _owner) public { require(msg.sender == admin); owner = _owner; } /// @notice Destroy the contract function kill() public onlyOwner { selfdestruct(payable(owner)); } /// @notice withdraw stuck funds function withdrawStuckFunds(address _token, uint _amount) public onlyOwner { if (_token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) { payable(owner).transfer(_amount); } else { ERC20(_token).safeTransfer(owner, _amount); } } } contract BotRegistry is AdminAuth { mapping (address => bool) public botList; constructor() public { botList[0x776B4a13093e30B05781F97F6A4565B6aa8BE330] = true; botList[0xAED662abcC4FA3314985E67Ea993CAD064a7F5cF] = true; botList[0xa5d330F6619d6bF892A5B87D80272e1607b3e34D] = true; botList[0x5feB4DeE5150B589a7f567EA7CADa2759794A90A] = true; botList[0x7ca06417c1d6f480d3bB195B80692F95A6B66158] = true; } function setBot(address _botAddr, bool _state) public onlyOwner { botList[_botAddr] = _state; } } contract AaveHelperV2 is DSMath { using SafeERC20 for ERC20; IFeeRecipient public constant feeRecipient = IFeeRecipient(0x39C4a92Dc506300c3Ea4c67ca4CA611102ee6F2A); address public constant DISCOUNT_ADDR = 0x1b14E8D511c9A4395425314f849bD737BAF8208F; address public constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; // mainnet uint public constant MANUAL_SERVICE_FEE = 400; // 0.25% Fee uint public constant AUTOMATIC_SERVICE_FEE = 333; // 0.3% Fee address public constant BOT_REGISTRY_ADDRESS = 0x637726f8b08a7ABE3aE3aCaB01A80E2d8ddeF77B; address public constant ETH_ADDR = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; uint public constant NINETY_NINE_PERCENT_WEI = 990000000000000000; uint16 public constant AAVE_REFERRAL_CODE = 64; uint public constant STABLE_ID = 1; uint public constant VARIABLE_ID = 2; /// @notice Calculates the gas cost for transaction /// @param _oracleAddress address of oracle used /// @param _amount Amount that is converted /// @param _gasCost Ether amount of gas we are spending for tx /// @param _tokenAddr token addr. of token we are getting for the fee /// @return gasCost The amount we took for the gas cost function getGasCost(address _oracleAddress, uint _amount, uint _gasCost, address _tokenAddr) internal returns (uint gasCost) { if (_gasCost == 0) return 0; // in case its ETH, we need to get price for WETH // everywhere else we still use ETH as thats the token we have in this moment address priceToken = _tokenAddr == ETH_ADDR ? WETH_ADDRESS : _tokenAddr; uint256 price = IPriceOracleGetterAave(_oracleAddress).getAssetPrice(priceToken); _gasCost = wdiv(_gasCost, price) / (10 ** (18 - _getDecimals(_tokenAddr))); gasCost = _gasCost; // gas cost can't go over 20% of the whole amount if (gasCost > (_amount / 5)) { gasCost = _amount / 5; } address walletAddr = feeRecipient.getFeeAddr(); if (gasCost > 0) { if (_tokenAddr == ETH_ADDR) { walletAddr.call{value: gasCost}(""); } else { ERC20(_tokenAddr).safeTransfer(walletAddr, gasCost); } } } /// @notice Returns the owner of the DSProxy that called the contract function getUserAddress() internal view returns (address) { DSProxy proxy = DSProxy(payable(address(this))); return proxy.owner(); } /// @notice Approves token contract to pull underlying tokens from the DSProxy /// @param _tokenAddr Token we are trying to approve /// @param _caller Address which will gain the approval function approveToken(address _tokenAddr, address _caller) internal { if (_tokenAddr != ETH_ADDR) { ERC20(_tokenAddr).safeApprove(_caller, uint256(-1)); } } /// @notice Send specific amount from contract to specific user /// @param _token Token we are trying to send /// @param _user User that should receive funds /// @param _amount Amount that should be sent function sendContractBalance(address _token, address _user, uint _amount) internal { if (_amount == 0) return; if (_token == ETH_ADDR) { payable(_user).transfer(_amount); } else { ERC20(_token).safeTransfer(_user, _amount); } } function sendFullContractBalance(address _token, address _user) internal { if (_token == ETH_ADDR) { sendContractBalance(_token, _user, address(this).balance); } else { sendContractBalance(_token, _user, ERC20(_token).balanceOf(address(this))); } } function _getDecimals(address _token) internal view returns (uint256) { if (_token == ETH_ADDR) return 18; return ERC20(_token).decimals(); } function getDataProvider(address _market) internal view returns(IAaveProtocolDataProviderV2) { return IAaveProtocolDataProviderV2(ILendingPoolAddressesProviderV2(_market).getAddress(0x0100000000000000000000000000000000000000000000000000000000000000)); } } interface ExchangeInterfaceV3 { function sell(address _srcAddr, address _destAddr, uint _srcAmount, bytes memory _additionalData) external payable returns (uint); function buy(address _srcAddr, address _destAddr, uint _destAmount, bytes memory _additionalData) external payable returns(uint); function getSellRate(address _srcAddr, address _destAddr, uint _srcAmount, bytes memory _additionalData) external returns (uint); function getBuyRate(address _srcAddr, address _destAddr, uint _srcAmount, bytes memory _additionalData) external returns (uint); } contract ZrxAllowlist is AdminAuth { mapping (address => bool) public zrxAllowlist; mapping(address => bool) private nonPayableAddrs; constructor() public { zrxAllowlist[0x6958F5e95332D93D21af0D7B9Ca85B8212fEE0A5] = true; zrxAllowlist[0x61935CbDd02287B511119DDb11Aeb42F1593b7Ef] = true; zrxAllowlist[0xDef1C0ded9bec7F1a1670819833240f027b25EfF] = true; zrxAllowlist[0x080bf510FCbF18b91105470639e9561022937712] = true; nonPayableAddrs[0x080bf510FCbF18b91105470639e9561022937712] = true; } function setAllowlistAddr(address _zrxAddr, bool _state) public onlyOwner { zrxAllowlist[_zrxAddr] = _state; } function isZrxAddr(address _zrxAddr) public view returns (bool) { return zrxAllowlist[_zrxAddr]; } function addNonPayableAddr(address _nonPayableAddr) public onlyOwner { nonPayableAddrs[_nonPayableAddr] = true; } function removeNonPayableAddr(address _nonPayableAddr) public onlyOwner { nonPayableAddrs[_nonPayableAddr] = false; } function isNonPayableAddr(address _addr) public view returns(bool) { return nonPayableAddrs[_addr]; } } contract DFSExchangeData { // first is empty to keep the legacy order in place enum ExchangeType { _, OASIS, KYBER, UNISWAP, ZEROX } enum ActionType { SELL, BUY } struct OffchainData { address wrapper; address exchangeAddr; address allowanceTarget; uint256 price; uint256 protocolFee; bytes callData; } struct ExchangeData { address srcAddr; address destAddr; uint256 srcAmount; uint256 destAmount; uint256 minPrice; uint256 dfsFeeDivider; // service fee divider address user; // user to check special fee address wrapper; bytes wrapperData; OffchainData offchainData; } function packExchangeData(ExchangeData memory _exData) public pure returns(bytes memory) { return abi.encode(_exData); } function unpackExchangeData(bytes memory _data) public pure returns(ExchangeData memory _exData) { _exData = abi.decode(_data, (ExchangeData)); } } contract DFSExchangeHelper { string public constant ERR_OFFCHAIN_DATA_INVALID = "Offchain data invalid"; using SafeERC20 for ERC20; address public constant KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public constant EXCHANGE_WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; IFeeRecipient public constant _feeRecipient = IFeeRecipient(0x39C4a92Dc506300c3Ea4c67ca4CA611102ee6F2A); address public constant DISCOUNT_ADDRESS = 0x1b14E8D511c9A4395425314f849bD737BAF8208F; address public constant SAVER_EXCHANGE_REGISTRY = 0x25dd3F51e0C3c3Ff164DDC02A8E4D65Bb9cBB12D; address public constant ZRX_ALLOWLIST_ADDR = 0x4BA1f38427b33B8ab7Bb0490200dAE1F1C36823F; function getDecimals(address _token) internal view returns (uint256) { if (_token == KYBER_ETH_ADDRESS) return 18; return ERC20(_token).decimals(); } function getBalance(address _tokenAddr) internal view returns (uint balance) { if (_tokenAddr == KYBER_ETH_ADDRESS) { balance = address(this).balance; } else { balance = ERC20(_tokenAddr).balanceOf(address(this)); } } function sendLeftover(address _srcAddr, address _destAddr, address payable _to) internal { // send back any leftover ether or tokens if (address(this).balance > 0) { _to.transfer(address(this).balance); } if (getBalance(_srcAddr) > 0) { ERC20(_srcAddr).safeTransfer(_to, getBalance(_srcAddr)); } if (getBalance(_destAddr) > 0) { ERC20(_destAddr).safeTransfer(_to, getBalance(_destAddr)); } } /// @notice Takes a feePercentage and sends it to wallet /// @param _amount Dai amount of the whole trade /// @param _user Address of the user /// @param _token Address of the token /// @param _dfsFeeDivider Dfs fee divider /// @return feeAmount Amount in Dai owner earned on the fee function getFee(uint256 _amount, address _user, address _token, uint256 _dfsFeeDivider) internal returns (uint256 feeAmount) { if (_dfsFeeDivider != 0 && Discount(DISCOUNT_ADDRESS).isCustomFeeSet(_user)) { _dfsFeeDivider = Discount(DISCOUNT_ADDRESS).getCustomServiceFee(_user); } if (_dfsFeeDivider == 0) { feeAmount = 0; } else { feeAmount = _amount / _dfsFeeDivider; // fee can't go over 10% of the whole amount if (feeAmount > (_amount / 10)) { feeAmount = _amount / 10; } address walletAddr = _feeRecipient.getFeeAddr(); if (_token == KYBER_ETH_ADDRESS) { payable(walletAddr).transfer(feeAmount); } else { ERC20(_token).safeTransfer(walletAddr, feeAmount); } } } function sliceUint(bytes memory bs, uint256 start) internal pure returns (uint256) { require(bs.length >= start + 32, "slicing out of range"); uint256 x; assembly { x := mload(add(bs, add(0x20, start))) } return x; } function writeUint256(bytes memory _b, uint256 _index, uint _input) internal pure { if (_b.length < _index + 32) { revert(ERR_OFFCHAIN_DATA_INVALID); } bytes32 input = bytes32(_input); _index += 32; // Read the bytes32 from array memory assembly { mstore(add(_b, _index), input) } } /// @notice Converts Kybers Eth address -> Weth /// @param _src Input address function ethToWethAddr(address _src) internal pure returns (address) { return _src == KYBER_ETH_ADDRESS ? EXCHANGE_WETH_ADDRESS : _src; } } contract SaverExchangeRegistry is AdminAuth { mapping(address => bool) private wrappers; constructor() public { wrappers[0x880A845A85F843a5c67DB2061623c6Fc3bB4c511] = true; wrappers[0x4c9B55f2083629A1F7aDa257ae984E03096eCD25] = true; wrappers[0x42A9237b872368E1bec4Ca8D26A928D7d39d338C] = true; } function addWrapper(address _wrapper) public onlyOwner { wrappers[_wrapper] = true; } function removeWrapper(address _wrapper) public onlyOwner { wrappers[_wrapper] = false; } function isWrapper(address _wrapper) public view returns(bool) { return wrappers[_wrapper]; } } abstract contract OffchainWrapperInterface is DFSExchangeData { function takeOrder( ExchangeData memory _exData, ActionType _type ) virtual public payable returns (bool success, uint256); } contract DFSExchangeCore is DFSExchangeHelper, DSMath, DFSExchangeData { string public constant ERR_SLIPPAGE_HIT = "Slippage hit"; string public constant ERR_DEST_AMOUNT_MISSING = "Dest amount missing"; string public constant ERR_WRAPPER_INVALID = "Wrapper invalid"; string public constant ERR_NOT_ZEROX_EXCHANGE = "Zerox exchange invalid"; /// @notice Internal method that preforms a sell on 0x/on-chain /// @dev Usefull for other DFS contract to integrate for exchanging /// @param exData Exchange data struct /// @return (address, uint) Address of the wrapper used and destAmount function _sell(ExchangeData memory exData) internal returns (address, uint) { address wrapper; uint swapedTokens; bool success; // if selling eth, convert to weth if (exData.srcAddr == KYBER_ETH_ADDRESS) { exData.srcAddr = ethToWethAddr(exData.srcAddr); TokenInterface(EXCHANGE_WETH_ADDRESS).deposit{value: exData.srcAmount}(); } exData.srcAmount -= getFee(exData.srcAmount, exData.user, exData.srcAddr, exData.dfsFeeDivider); // Try 0x first and then fallback on specific wrapper if (exData.offchainData.price > 0) { (success, swapedTokens) = takeOrder(exData, ActionType.SELL); if (success) { wrapper = exData.offchainData.exchangeAddr; } } // fallback to desired wrapper if 0x failed if (!success) { swapedTokens = saverSwap(exData, ActionType.SELL); wrapper = exData.wrapper; } // if anything is left in weth, pull it to user as eth if (getBalance(EXCHANGE_WETH_ADDRESS) > 0) { TokenInterface(EXCHANGE_WETH_ADDRESS).withdraw( TokenInterface(EXCHANGE_WETH_ADDRESS).balanceOf(address(this)) ); } if (exData.destAddr == EXCHANGE_WETH_ADDRESS) { require(getBalance(KYBER_ETH_ADDRESS) >= wmul(exData.minPrice, exData.srcAmount), ERR_SLIPPAGE_HIT); } else { require(getBalance(exData.destAddr) >= wmul(exData.minPrice, exData.srcAmount), ERR_SLIPPAGE_HIT); } return (wrapper, swapedTokens); } /// @notice Internal method that preforms a buy on 0x/on-chain /// @dev Usefull for other DFS contract to integrate for exchanging /// @param exData Exchange data struct /// @return (address, uint) Address of the wrapper used and srcAmount function _buy(ExchangeData memory exData) internal returns (address, uint) { address wrapper; uint swapedTokens; bool success; require(exData.destAmount != 0, ERR_DEST_AMOUNT_MISSING); exData.srcAmount -= getFee(exData.srcAmount, exData.user, exData.srcAddr, exData.dfsFeeDivider); // if selling eth, convert to weth if (exData.srcAddr == KYBER_ETH_ADDRESS) { exData.srcAddr = ethToWethAddr(exData.srcAddr); TokenInterface(EXCHANGE_WETH_ADDRESS).deposit{value: exData.srcAmount}(); } if (exData.offchainData.price > 0) { (success, swapedTokens) = takeOrder(exData, ActionType.BUY); if (success) { wrapper = exData.offchainData.exchangeAddr; } } // fallback to desired wrapper if 0x failed if (!success) { swapedTokens = saverSwap(exData, ActionType.BUY); wrapper = exData.wrapper; } // if anything is left in weth, pull it to user as eth if (getBalance(EXCHANGE_WETH_ADDRESS) > 0) { TokenInterface(EXCHANGE_WETH_ADDRESS).withdraw( TokenInterface(EXCHANGE_WETH_ADDRESS).balanceOf(address(this)) ); } if (exData.destAddr == EXCHANGE_WETH_ADDRESS) { require(getBalance(KYBER_ETH_ADDRESS) >= exData.destAmount, ERR_SLIPPAGE_HIT); } else { require(getBalance(exData.destAddr) >= exData.destAmount, ERR_SLIPPAGE_HIT); } return (wrapper, getBalance(exData.destAddr)); } /// @notice Takes order from 0x and returns bool indicating if it is successful /// @param _exData Exchange data function takeOrder( ExchangeData memory _exData, ActionType _type ) private returns (bool success, uint256) { if (!ZrxAllowlist(ZRX_ALLOWLIST_ADDR).isZrxAddr(_exData.offchainData.exchangeAddr)) { return (false, 0); } if (!SaverExchangeRegistry(SAVER_EXCHANGE_REGISTRY).isWrapper(_exData.offchainData.wrapper)) { return (false, 0); } // send src amount ERC20(_exData.srcAddr).safeTransfer(_exData.offchainData.wrapper, _exData.srcAmount); return OffchainWrapperInterface(_exData.offchainData.wrapper).takeOrder{value: _exData.offchainData.protocolFee}(_exData, _type); } /// @notice Calls wraper contract for exchage to preform an on-chain swap /// @param _exData Exchange data struct /// @param _type Type of action SELL|BUY /// @return swapedTokens For Sell that the destAmount, for Buy thats the srcAmount function saverSwap(ExchangeData memory _exData, ActionType _type) internal returns (uint swapedTokens) { require(SaverExchangeRegistry(SAVER_EXCHANGE_REGISTRY).isWrapper(_exData.wrapper), ERR_WRAPPER_INVALID); ERC20(_exData.srcAddr).safeTransfer(_exData.wrapper, _exData.srcAmount); if (_type == ActionType.SELL) { swapedTokens = ExchangeInterfaceV3(_exData.wrapper). sell(_exData.srcAddr, _exData.destAddr, _exData.srcAmount, _exData.wrapperData); } else { swapedTokens = ExchangeInterfaceV3(_exData.wrapper). buy(_exData.srcAddr, _exData.destAddr, _exData.destAmount, _exData.wrapperData); } } // solhint-disable-next-line no-empty-blocks receive() external virtual payable {} } contract DefisaverLogger { event LogEvent( address indexed contractAddress, address indexed caller, string indexed logName, bytes data ); // solhint-disable-next-line func-name-mixedcase function Log(address _contract, address _caller, string memory _logName, bytes memory _data) public { emit LogEvent(_contract, _caller, _logName, _data); } } /// @title Import Aave position from account to wallet contract AaveSaverReceiverOV2 is AaveHelperV2, AdminAuth, DFSExchangeCore { using SafeERC20 for ERC20; address public constant DEFISAVER_LOGGER = 0x5c55B921f590a89C1Ebe84dF170E655a82b62126; address public constant AAVE_BASIC_PROXY = 0xFF40D4FB79b3B5AD3b0cc2d29D2436A488cA45Ef; function boost( ExchangeData memory _exchangeData, address _market, uint256 _gasCost, address _proxy ) internal { uint256 swappedAmount = _exchangeData.srcAmount; // handle same asset boost if (_exchangeData.srcAddr != _exchangeData.destAddr) { (, swappedAmount) = _sell(_exchangeData); } swappedAmount = sub(swappedAmount, getGasCost( ILendingPoolAddressesProviderV2(_market).getPriceOracle(), swappedAmount, _gasCost, _exchangeData.destAddr )); // if its eth we need to send it to the basic proxy, if not, we need to approve users proxy to pull tokens uint256 msgValue = 0; address token = _exchangeData.destAddr; // sell always return eth, but deposit differentiate eth vs weth, so we change weth address to eth when we are depoisting if (_exchangeData.destAddr == ETH_ADDR || _exchangeData.destAddr == WETH_ADDRESS) { msgValue = swappedAmount; token = ETH_ADDR; } else { ERC20(_exchangeData.destAddr).safeApprove(_proxy, swappedAmount); } // deposit collateral on behalf of user DSProxy(payable(_proxy)).execute{value: msgValue}( AAVE_BASIC_PROXY, abi.encodeWithSignature( "deposit(address,address,uint256)", _market, token, swappedAmount ) ); logEvent("AaveV2Boost", _exchangeData, swappedAmount); } function repay( ExchangeData memory _exchangeData, address _market, uint256 _gasCost, address _proxy, uint256 _rateMode, uint256 _aaveFlashlLoanFee ) internal { // we will withdraw exactly the srcAmount, as fee we keep before selling uint256 valueToWithdraw = _exchangeData.srcAmount; // take out the fee wee need to pay and sell the rest _exchangeData.srcAmount = sub(_exchangeData.srcAmount, _aaveFlashlLoanFee); uint256 swappedAmount = _exchangeData.srcAmount; // don't sell if its the same token if (_exchangeData.srcAddr != _exchangeData.destAddr) { (, swappedAmount) = _sell(_exchangeData); } address user = DSAuth(_proxy).owner(); swappedAmount = sub(swappedAmount, getGasCost( ILendingPoolAddressesProviderV2(_market).getPriceOracle(), swappedAmount, _gasCost, _exchangeData.destAddr )); // set protocol fee left to eth balance of this address // but if destAddr is eth or weth, this also includes that value so we need to substract it // doing this after taking gas cost so it doesn't take it into account uint256 protocolFeeLeft = address(this).balance; // if its eth we need to send it to the basic proxy, if not, we need to approve basic proxy to pull tokens uint256 msgValue = 0; if (_exchangeData.destAddr == ETH_ADDR || _exchangeData.destAddr == WETH_ADDRESS) { protocolFeeLeft = sub(protocolFeeLeft, swappedAmount); msgValue = swappedAmount; } else { ERC20(_exchangeData.destAddr).safeApprove(_proxy, swappedAmount); } // if we don't have enough eth for payback, try and unwrap weth if (address(this).balance < msgValue) { TokenInterface(WETH_ADDRESS).withdraw(msgValue); } // first payback the loan with swapped amount // this payback will return funds that left directly to the user DSProxy(payable(_proxy)).execute{value: msgValue}( AAVE_BASIC_PROXY, abi.encodeWithSignature( "paybackAndReturnToUser(address,address,uint256,uint256,address)", _market, _exchangeData.destAddr, swappedAmount, _rateMode, user ) ); // pull the amount we flash loaned in collateral to be able to payback the debt DSProxy(payable(_proxy)).execute( AAVE_BASIC_PROXY, abi.encodeWithSignature( "withdraw(address,address,uint256)", _market, _exchangeData.srcAddr, valueToWithdraw ) ); logEvent("AaveV2Repay", _exchangeData, swappedAmount); } function executeOperation( address[] calldata, uint256[] calldata, uint256[] calldata premiums, address initiator, bytes calldata params ) public returns (bool) { ( bytes memory exchangeDataBytes, address market, uint256 gasCost, uint256 rateMode, bool isRepay, address proxy ) = abi.decode(params, (bytes, address, uint256, uint256, bool, address)); address lendingPool = ILendingPoolAddressesProviderV2(market).getLendingPool(); require(msg.sender == lendingPool, "Callbacks only allowed from Aave"); require(initiator == proxy, "Initiator isn't proxy"); ExchangeData memory exData = unpackExchangeData(exchangeDataBytes); exData.user = DSAuth(proxy).owner(); exData.dfsFeeDivider = MANUAL_SERVICE_FEE; if (BotRegistry(BOT_REGISTRY_ADDRESS).botList(tx.origin)) { exData.dfsFeeDivider = AUTOMATIC_SERVICE_FEE; } // this is to avoid stack too deep uint256 fee = premiums[0]; uint256 totalValueToReturn = exData.srcAmount + fee; // if its repay, we are using regular flash loan and payback the premiums if (isRepay) { repay(exData, market, gasCost, proxy, rateMode, fee); address token = exData.srcAddr; if (token == ETH_ADDR || token == WETH_ADDRESS) { // deposit eth, get weth and return to sender TokenInterface(WETH_ADDRESS).deposit.value(totalValueToReturn)(); token = WETH_ADDRESS; } ERC20(token).safeApprove(lendingPool, totalValueToReturn); } else { boost(exData, market, gasCost, proxy); } tx.origin.transfer(address(this).balance); return true; } /// @dev Wrapped in a separate function to avoid stack too deep function logEvent(string memory _name, ExchangeData memory _exchangeData, uint _swappedAmount) internal { DefisaverLogger(DEFISAVER_LOGGER).Log( address(this), msg.sender, _name, abi.encode(_exchangeData.srcAddr, _exchangeData.destAddr, _exchangeData.srcAmount, _swappedAmount) ); } /// @dev allow contract to receive eth from sell receive() external payable override {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"AAVE_BASIC_PROXY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AAVE_REFERRAL_CODE","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AUTOMATIC_SERVICE_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BOT_REGISTRY_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFISAVER_LOGGER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DISCOUNT_ADDR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DISCOUNT_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_DEST_AMOUNT_MISSING","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_NOT_ZEROX_EXCHANGE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_OFFCHAIN_DATA_INVALID","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_SLIPPAGE_HIT","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_WRAPPER_INVALID","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_ADDR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXCHANGE_WETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"KYBER_ETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANUAL_SERVICE_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NINETY_NINE_PERCENT_WEI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SAVER_EXCHANGE_REGISTRY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STABLE_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VARIABLE_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ZRX_ALLOWLIST_ADDR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_feeRecipient","outputs":[{"internalType":"contract IFeeRecipient","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","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":[],"name":"feeRecipient","outputs":[{"internalType":"contract IFeeRecipient","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kill","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcAddr","type":"address"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"dfsFeeDivider","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"bytes","name":"wrapperData","type":"bytes"},{"components":[{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"address","name":"allowanceTarget","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct DFSExchangeData.OffchainData","name":"offchainData","type":"tuple"}],"internalType":"struct DFSExchangeData.ExchangeData","name":"_exData","type":"tuple"}],"name":"packExchangeData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdminByAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdminByOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwnerByAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"unpackExchangeData","outputs":[{"components":[{"internalType":"address","name":"srcAddr","type":"address"},{"internalType":"address","name":"destAddr","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"dfsFeeDivider","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"bytes","name":"wrapperData","type":"bytes"},{"components":[{"internalType":"address","name":"wrapper","type":"address"},{"internalType":"address","name":"exchangeAddr","type":"address"},{"internalType":"address","name":"allowanceTarget","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct DFSExchangeData.OffchainData","name":"offchainData","type":"tuple"}],"internalType":"struct DFSExchangeData.ExchangeData","name":"_exData","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawStuckFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b50600080546001600160a01b031990811673bc841b0de0b93205e912cfbbd1d0c160a1ec6f0017909155600180549091167325efa336886c74ea8e282ac466bdcd0199f85bb9179055612fc7806100686000396000f3fe6080604052600436106101fd5760003560e01c80637b925ab11161010d578063a46a66c9116100a0578063c50ebaf81161006f578063c50ebaf8146104b1578063cc694d48146104c6578063d4f922dc146104db578063deca5f88146104f0578063f851a4401461051057610204565b8063a46a66c9146103b9578063a7304bf714610467578063ae08fd1014610487578063b13cdb201461049c57610204565b80638da5cb5b116100dc5780638da5cb5b146103f8578063920f5c841461040d578063a342f2381461037a578063a3b8e5d11461043a57610204565b80637b925ab1146103b957806381b9428014610209578063870e44d9146103ce5780638c8a7958146103e357610204565b8063314b633211610190578063449b9ffa1161015f578063449b9ffa14610365578063469048401461037a5780634d2ab9dc1461038f578063526d6461146103a45780637753f47b146102dc57610204565b8063314b63321461030657806339df18781461031b5780633a1283221461033057806341c0e1b51461035057610204565b80631e48907b116101cc5780631e48907b146102a5578063278d5831146102c757806329f7fc9e146102dc5780632ba38bcb146102f157610204565b8063040141e51461020957806304c9805c1461023457806305a363de1461025657806308d4f52a1461027857610204565b3661020457005b600080fd5b34801561021557600080fd5b5061021e610525565b60405161022b9190612bf0565b60405180910390f35b34801561024057600080fd5b50610249610537565b60405161022b9190612ea7565b34801561026257600080fd5b5061026b61053d565b60405161022b9190612e98565b34801561028457600080fd5b50610298610293366004612895565b610542565b60405161022b9190612d61565b3480156102b157600080fd5b506102c56102c036600461261a565b61056c565b005b3480156102d357600080fd5b506102986105a5565b3480156102e857600080fd5b5061021e6105cd565b3480156102fd57600080fd5b506102496105df565b34801561031257600080fd5b5061021e6105e4565b34801561032757600080fd5b5061021e6105fc565b34801561033c57600080fd5b506102c561034b366004612652565b610614565b34801561035c57600080fd5b506102c56106a7565b34801561037157600080fd5b506102986106cc565b34801561038657600080fd5b5061021e6106fe565b34801561039b57600080fd5b50610249610716565b3480156103b057600080fd5b5061021e61071c565b3480156103c557600080fd5b5061021e610734565b3480156103da57600080fd5b5061024961074c565b3480156103ef57600080fd5b5061021e610758565b34801561040457600080fd5b5061021e610770565b34801561041957600080fd5b5061042d61042836600461267d565b61077f565b60405161022b9190612d56565b34801561044657600080fd5b5061045a6104553660046127db565b610b01565b60405161022b9190612e59565b34801561047357600080fd5b506102c561048236600461261a565b610b23565b34801561049357600080fd5b50610298610b5c565b3480156104a857600080fd5b5061021e610b8d565b3480156104bd57600080fd5b50610298610ba5565b3480156104d257600080fd5b50610298610bd4565b3480156104e757600080fd5b50610249610bff565b3480156104fc57600080fd5b506102c561050b36600461261a565b610c04565b34801561051c57600080fd5b5061021e610c31565b600080516020612f5283398151915281565b61014d81565b604081565b6060816040516020016105559190612e59565b60405160208183030381529060405290505b919050565b6001546001600160a01b0316331461058357600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b81525081565b600080516020612f7283398151915281565b600181565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b735c55b921f590a89c1ebe84df170e655a82b6212681565b6000546001600160a01b0316331461062b57600080fd5b600080516020612f728339815191526001600160a01b038316141561068957600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610683573d6000803e3d6000fd5b506106a3565b6000546106a3906001600160a01b03848116911683610c40565b5050565b6000546001600160a01b031633146106be57600080fd5b6000546001600160a01b0316ff5b6040518060400160405280601681526020017516995c9bde08195e18da185b99d9481a5b9d985b1a5960521b81525081565b7339c4a92dc506300c3ea4c67ca4ca611102ee6f2a81565b61019081565b73637726f8b08a7abe3ae3acab01a80e2d8ddef77b81565b731b14e8d511c9a4395425314f849bd737baf8208f81565b670dbd2fc137a3000081565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6000546001600160a01b031681565b600060608180808080610794888a018a61280e565b9550955095509550955095506000856001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107db57600080fd5b505afa1580156107ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108139190612636565b9050336001600160a01b038216146108465760405162461bcd60e51b815260040161083d90612d74565b60405180910390fd5b816001600160a01b03168b6001600160a01b0316146108775760405162461bcd60e51b815260040161083d90612da9565b61087f612331565b61088888610b01565b9050826001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156108c357600080fd5b505afa1580156108d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fb9190612636565b6001600160a01b031660c082015261019060a08201526040516320eb73ed60e11b815273637726f8b08a7abe3ae3acab01a80e2d8ddef77b906341d6e7da90610948903290600401612bf0565b60206040518083038186803b15801561096057600080fd5b505afa158015610974573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610998919061277a565b156109a65761014d60a08201525b60008e8e60008181106109b557fe5b90506020020135905060008183604001510190508515610aad576109dd838a8a888b87610c9b565b82516001600160a01b038116600080516020612f728339815191521480610a1a57506001600160a01b038116600080516020612f52833981519152145b15610a9357600080516020612f528339815191526001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015610a6857600080fd5b505af1158015610a7c573d6000803e3d6000fd5b5050505050600080516020612f5283398151915290505b610aa76001600160a01b03821686846110b2565b50610ab9565b610ab9838a8a886110f1565b60405132904780156108fc02916000818181858888f19350505050158015610ae5573d6000803e3d6000fd5b5060019a50505050505050505050509998505050505050505050565b610b09612331565b81806020019051810190610b1d919061299d565b92915050565b6001546001600160a01b03163314610b3a57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280601581526020017413d99998da185a5b8819185d18481a5b9d985b1a59605a1b81525081565b73ff40d4fb79b3b5ad3b0cc2d29d2436a488ca45ef81565b604051806040016040528060138152602001724465737420616d6f756e74206d697373696e6760681b81525081565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525081565b600281565b6000546001600160a01b03163314610c1b57600080fd5b6001546001600160a01b031615610b3a57600080fd5b6001546001600160a01b031681565b610c968363a9059cbb60e01b8484604051602401610c5f929190612d3d565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261132e565b505050565b6040860151610caa81836113bd565b60408801819052602088015188516001600160a01b03908116911614610cd757610cd3886113cd565b9150505b6000856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d1257600080fd5b505afa158015610d26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4a9190612636565b9050610dd582610dd08a6001600160a01b031663fca513a86040518163ffffffff1660e01b815260040160206040518083038186803b158015610d8c57600080fd5b505afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190612636565b858b8e602001516116f0565b6113bd565b60208a015190925047906000906001600160a01b0316600080516020612f728339815191521480610e20575060208b01516001600160a01b0316600080516020612f52833981519152145b15610e3957610e2f82856113bd565b9150839050610e52565b60208b0151610e52906001600160a01b031689866110b2565b80471015610ebe57604051632e1a7d4d60e01b8152600080516020612f5283398151915290632e1a7d4d90610e8b908490600401612ea7565b600060405180830381600087803b158015610ea557600080fd5b505af1158015610eb9573d6000803e3d6000fd5b505050505b876001600160a01b0316631cff79cd8273ff40d4fb79b3b5ad3b0cc2d29d2436a488ca45ef8d8f60200151898d8a604051602401610f00959493929190612ccd565b60408051601f198184030181529181526020820180516001600160e01b0316632c6951f360e21b1790525160e085901b6001600160e01b0319168152610f4a929190600401612cfd565b6020604051808303818588803b158015610f6357600080fd5b505af1158015610f77573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610f9c91906127c3565b50876001600160a01b0316631cff79cd73ff40d4fb79b3b5ad3b0cc2d29d2436a488ca45ef8c8e6000015189604051602401610fda93929190612c4d565b60408051601f198184030181529181526020820180516001600160e01b0316636ce5768960e11b1790525160e084901b6001600160e01b0319168152611024929190600401612cfd565b602060405180830381600087803b15801561103e57600080fd5b505af1158015611052573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107691906127c3565b506110a56040518060400160405280600b81526020016a416176655632526570617960a81b8152508c8661191e565b5050505050505050505050565b6110d28363095ea7b360e01b846000604051602401610c5f929190612d21565b610c968363095ea7b360e01b8484604051602401610c5f929190612d3d565b6040840151602085015185516001600160a01b0390811691161461111c57611118856113cd565b9150505b6111a081610dd0866001600160a01b031663fca513a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561115c57600080fd5b505afa158015611170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111949190612636565b84878a602001516116f0565b60208601519091506000906001600160a01b038116600080516020612f7283398151915214806111ea575060208701516001600160a01b0316600080516020612f52833981519152145b156112075750819050600080516020612f72833981519152611220565b6020870151611220906001600160a01b031685856110b2565b836001600160a01b0316631cff79cd8373ff40d4fb79b3b5ad3b0cc2d29d2436a488ca45ef89858860405160240161125a93929190612c4d565b60408051601f198184030181529181526020820180516001600160e01b0316638340f54960e01b1790525160e085901b6001600160e01b03191681526112a4929190600401612cfd565b6020604051808303818588803b1580156112bd57600080fd5b505af11580156112d1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906112f691906127c3565b506113256040518060400160405280600b81526020016a10585d99558c909bdbdcdd60aa1b815250888561191e565b50505050505050565b6060611383826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166119c39092919063ffffffff16565b805190915015610c9657808060200190518101906113a1919061277a565b610c965760405162461bcd60e51b815260040161083d90612e0f565b80820382811115610b1d57600080fd5b6000806000806000600080516020612f728339815191526001600160a01b031686600001516001600160a01b0316141561147c57855161140c906119d2565b6001600160a01b031686526040808701518151630d0e30db60e41b81529151600080516020612f528339815191529263d0e30db09291600480830192600092919082900301818588803b15801561146257600080fd5b505af1158015611476573d6000803e3d6000fd5b50505050505b61149886604001518760c0015188600001518960a00151611a0d565b60408701805191909103905261012086015160600151156114d5576114be866000611c5a565b9250905080156114d5578561012001516020015192505b806114ef576114e5866000611e58565b91508560e0015192505b6000611508600080516020612f528339815191526120a1565b11156115e8576040516370a0823160e01b8152600080516020612f5283398151915290632e1a7d4d9082906370a0823190611547903090600401612bf0565b602060405180830381600087803b15801561156157600080fd5b505af1158015611575573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159991906127c3565b6040518263ffffffff1660e01b81526004016115b59190612ea7565b600060405180830381600087803b1580156115cf57600080fd5b505af11580156115e3573d6000803e3d6000fd5b505050505b60208601516001600160a01b0316600080516020612f52833981519152141561167f5761161d86608001518760400151612145565b611634600080516020612f728339815191526120a1565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906116795760405162461bcd60e51b815260040161083d9190612d61565b506116e5565b61169186608001518760400151612145565b61169e87602001516120a1565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906116e35760405162461bcd60e51b815260040161083d9190612d61565b505b509092509050915091565b6000826116ff57506000611916565b60006001600160a01b038316600080516020612f72833981519152146117255782611735565b600080516020612f528339815191525b90506000866001600160a01b031663b3596f07836040518263ffffffff1660e01b81526004016117659190612bf0565b60206040518083038186803b15801561177d57600080fd5b505afa158015611791573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b591906127c3565b90506117c08461217e565b601203600a0a6117d086836121e0565b816117d757fe5b049450849250600586048311156117ef576005860492505b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561183e57600080fd5b505afa158015611852573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118769190612636565b90508315611912576001600160a01b038516600080516020612f7283398151915214156118fe57806001600160a01b0316846040516118b490612bed565b60006040518083038185875af1925050503d80600081146118f1576040519150601f19603f3d011682016040523d82523d6000602084013e6118f6565b606091505b505050611912565b6119126001600160a01b0386168286610c40565b5050505b949350505050565b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce50303386866000015187602001518860400151886040516020016119679493929190612ca4565b6040516020818303038152906040526040518563ffffffff1660e01b81526004016119959493929190612c04565b600060405180830381600087803b1580156119af57600080fd5b505af1158015611325573d6000803e3d6000fd5b60606119168484600085612200565b60006001600160a01b038216600080516020612f72833981519152146119f85781610b1d565b50600080516020612f52833981519152919050565b60008115801590611aa05750604051632cdc77ab60e21b8152731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac90611a50908790600401612bf0565b60206040518083038186803b158015611a6857600080fd5b505afa158015611a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa0919061277a565b15611b2f57604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb543190611adc908790600401612bf0565b60206040518083038186803b158015611af457600080fd5b505afa158015611b08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2c91906127c3565b91505b81611b3c57506000611916565b818581611b4557fe5b049050600a8504811115611b595750600a84045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ba857600080fd5b505afa158015611bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be09190612636565b90506001600160a01b038416600080516020612f728339815191521415611c3d576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015611c37573d6000803e3d6000fd5b50611c51565b611c516001600160a01b0385168284610c40565b50949350505050565b610120820151602001516040516302f5cc7960e11b81526000918291734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f291611c9f9190600401612bf0565b60206040518083038186803b158015611cb757600080fd5b505afa158015611ccb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cef919061277a565b611cfe57506000905080611e51565b6101208401515160405163e0aa279760e01b81527325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa279791611d3b9190600401612bf0565b60206040518083038186803b158015611d5357600080fd5b505afa158015611d67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d8b919061277a565b611d9a57506000905080611e51565b6101208401515160408501518551611dbd926001600160a01b0390911691610c40565b610120840151805160809091015160405163097396a160e31b81526001600160a01b0390921691634b9cb5089190611dfb9088908890600401612e6c565b60408051808303818588803b158015611e1357600080fd5b505af1158015611e27573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e4c9190612796565b915091505b9250929050565b60e082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa279791611e9591600401612bf0565b60206040518083038186803b158015611ead57600080fd5b505afa158015611ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee5919061277a565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525090611f2b5760405162461bcd60e51b815260040161083d9190612d61565b5060e083015160408401518451611f4d926001600160a01b0390911691610c40565b6000826001811115611f5b57fe5b1415612001578260e001516001600160a01b0316635b6f36fc8460000151856020015186604001518761010001516040518563ffffffff1660e01b8152600401611fa89493929190612c71565b602060405180830381600087803b158015611fc257600080fd5b505af1158015611fd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ffa91906127c3565b9050610b1d565b8260e001516001600160a01b0316633924db668460000151856020015186606001518761010001516040518563ffffffff1660e01b81526004016120489493929190612c71565b602060405180830381600087803b15801561206257600080fd5b505af1158015612076573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209a91906127c3565b9392505050565b60006001600160a01b038216600080516020612f7283398151915214156120c9575047610567565b6040516370a0823160e01b81526001600160a01b038316906370a08231906120f5903090600401612bf0565b60206040518083038186803b15801561210d57600080fd5b505afa158015612121573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1d91906127c3565b6000670de0b6b3a764000061216f61215d85856122c4565b6002670de0b6b3a76400005b046122e8565b8161217657fe5b049392505050565b60006001600160a01b038216600080516020612f7283398151915214156121a757506012610567565b816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561210d57600080fd5b60008161216f6121f885670de0b6b3a76400006122c4565b600285612169565b606061220b856122f8565b6122275760405162461bcd60e51b815260040161083d90612dd8565b60006060866001600160a01b031685876040516122449190612bd1565b60006040518083038185875af1925050503d8060008114612281576040519150601f19603f3d011682016040523d82523d6000602084013e612286565b606091505b5091509150811561229a5791506119169050565b8051156122aa5780518082602001fd5b8360405162461bcd60e51b815260040161083d9190612d61565b60008115806122df575050808202828282816122dc57fe5b04145b610b1d57600080fd5b80820182811015610b1d57600080fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611916575050151592915050565b60405180610140016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016123a86123ad565b905290565b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b8035610b1d81612f2b565b8051610b1d81612f2b565b60008083601f840112612425578182fd5b50813567ffffffffffffffff81111561243c578182fd5b6020830191508360208083028501011115611e5157600080fd5b600082601f830112612466578081fd5b813561247961247482612ed7565b612eb0565b915080825283602082850101111561249057600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126124b9578081fd5b81516124c761247482612ed7565b91508082528360208285010111156124de57600080fd5b6124ef816020840160208601612efb565b5092915050565b600060c08284031215612507578081fd5b61251160c0612eb0565b9050813561251e81612f2b565b8152602082013561252e81612f2b565b6020820152604082013561254181612f2b565b80604083015250606082013560608201526080820135608082015260a082013567ffffffffffffffff81111561257657600080fd5b61258284828501612456565b60a08301525092915050565b600060c0828403121561259f578081fd5b6125a960c0612eb0565b905081516125b681612f2b565b815260208201516125c681612f2b565b602082015260408201516125d981612f2b565b80604083015250606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561260e57600080fd5b612582848285016124a9565b60006020828403121561262b578081fd5b813561209a81612f2b565b600060208284031215612647578081fd5b815161209a81612f2b565b60008060408385031215612664578081fd5b823561266f81612f2b565b946020939093013593505050565b600080600080600080600080600060a08a8c03121561269a578485fd5b893567ffffffffffffffff808211156126b1578687fd5b6126bd8d838e01612414565b909b50995060208c01359150808211156126d5578687fd5b6126e18d838e01612414565b909950975060408c01359150808211156126f9578687fd5b6127058d838e01612414565b909750955060608c0135915061271a82612f2b565b90935060808b0135908082111561272f578384fd5b818c0191508c601f830112612742578384fd5b813581811115612750578485fd5b8d6020828501011115612761578485fd5b6020830194508093505050509295985092959850929598565b60006020828403121561278b578081fd5b815161209a81612f43565b600080604083850312156127a8578182fd5b82516127b381612f43565b6020939093015192949293505050565b6000602082840312156127d4578081fd5b5051919050565b6000602082840312156127ec578081fd5b813567ffffffffffffffff811115612802578182fd5b61191684828501612456565b60008060008060008060c08789031215612826578384fd5b863567ffffffffffffffff81111561283c578485fd5b61284889828a01612456565b965050602087013561285981612f2b565b94506040870135935060608701359250608087013561287781612f43565b915060a087013561288781612f2b565b809150509295509295509295565b6000602082840312156128a6578081fd5b813567ffffffffffffffff808211156128bd578283fd5b81840191506101408083870312156128d3578384fd5b6128dc81612eb0565b90506128e886846123fe565b81526128f786602085016123fe565b602082015260408301356040820152606083013560608201526080830135608082015260a083013560a08201526129318660c085016123fe565b60c08201526129438660e085016123fe565b60e0820152610100808401358381111561295b578586fd5b61296788828701612456565b8284015250506101208084013583811115612980578586fd5b61298c888287016124f6565b918301919091525095945050505050565b6000602082840312156129ae578081fd5b815167ffffffffffffffff808211156129c5578283fd5b81840191506101408083870312156129db578384fd5b6129e481612eb0565b90506129f08684612409565b81526129ff8660208501612409565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a0820152612a398660c08501612409565b60c0820152612a4b8660e08501612409565b60e08201526101008084015183811115612a63578586fd5b612a6f888287016124a9565b8284015250506101208084015183811115612a88578586fd5b61298c8882870161258e565b6001600160a01b03169052565b60008151808452612ab9816020860160208601612efb565b601f01601f19169290920160200192915050565b6000610140612add848451612a94565b6020830151612aef6020860182612a94565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c0830151612b2a60c0860182612a94565b5060e0830151612b3d60e0860182612a94565b50610100808401518282870152612b5683870182612aa1565b925050506101208084015185830382870152612b728382612b7c565b9695505050505050565b600060018060a01b0380835116845280602084015116602085015280604084015116604085015250606082015160608401526080820151608084015260a082015160c060a085015261191660c0850182612aa1565b60008251612be3818460208701612efb565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b03858116825284166020820152608060408201819052600090612c3090830185612aa1565b8281036060840152612c428185612aa1565b979650505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612b7290830184612aa1565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b039586168152938516602085015260408401929092526060830152909116608082015260a00190565b6001600160a01b038316815260406020820181905260009061191690830184612aa1565b6001600160a01b0392909216825260ff16602082015260400190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b60006020825261209a6020830184612aa1565b6020808252818101527f43616c6c6261636b73206f6e6c7920616c6c6f7765642066726f6d2041617665604082015260600190565b602080825260159082015274496e69746961746f722069736e27742070726f787960581b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60006020825261209a6020830184612acd565b600060408252612e7f6040830185612acd565b905060028310612e8b57fe5b8260208301529392505050565b61ffff91909116815260200190565b90815260200190565b60405181810167ffffffffffffffff81118282101715612ecf57600080fd5b604052919050565b600067ffffffffffffffff821115612eed578081fd5b50601f01601f191660200190565b60005b83811015612f16578181015183820152602001612efe565b83811115612f25576000848401525b50505050565b6001600160a01b0381168114612f4057600080fd5b50565b8015158114612f4057600080fdfe000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeea2646970667358221220df5120c60243d86910b9ede766ef34aab2059edd91f9622bb933ff38089f105c64736f6c634300060c0033
Deployed Bytecode
0x6080604052600436106101fd5760003560e01c80637b925ab11161010d578063a46a66c9116100a0578063c50ebaf81161006f578063c50ebaf8146104b1578063cc694d48146104c6578063d4f922dc146104db578063deca5f88146104f0578063f851a4401461051057610204565b8063a46a66c9146103b9578063a7304bf714610467578063ae08fd1014610487578063b13cdb201461049c57610204565b80638da5cb5b116100dc5780638da5cb5b146103f8578063920f5c841461040d578063a342f2381461037a578063a3b8e5d11461043a57610204565b80637b925ab1146103b957806381b9428014610209578063870e44d9146103ce5780638c8a7958146103e357610204565b8063314b633211610190578063449b9ffa1161015f578063449b9ffa14610365578063469048401461037a5780634d2ab9dc1461038f578063526d6461146103a45780637753f47b146102dc57610204565b8063314b63321461030657806339df18781461031b5780633a1283221461033057806341c0e1b51461035057610204565b80631e48907b116101cc5780631e48907b146102a5578063278d5831146102c757806329f7fc9e146102dc5780632ba38bcb146102f157610204565b8063040141e51461020957806304c9805c1461023457806305a363de1461025657806308d4f52a1461027857610204565b3661020457005b600080fd5b34801561021557600080fd5b5061021e610525565b60405161022b9190612bf0565b60405180910390f35b34801561024057600080fd5b50610249610537565b60405161022b9190612ea7565b34801561026257600080fd5b5061026b61053d565b60405161022b9190612e98565b34801561028457600080fd5b50610298610293366004612895565b610542565b60405161022b9190612d61565b3480156102b157600080fd5b506102c56102c036600461261a565b61056c565b005b3480156102d357600080fd5b506102986105a5565b3480156102e857600080fd5b5061021e6105cd565b3480156102fd57600080fd5b506102496105df565b34801561031257600080fd5b5061021e6105e4565b34801561032757600080fd5b5061021e6105fc565b34801561033c57600080fd5b506102c561034b366004612652565b610614565b34801561035c57600080fd5b506102c56106a7565b34801561037157600080fd5b506102986106cc565b34801561038657600080fd5b5061021e6106fe565b34801561039b57600080fd5b50610249610716565b3480156103b057600080fd5b5061021e61071c565b3480156103c557600080fd5b5061021e610734565b3480156103da57600080fd5b5061024961074c565b3480156103ef57600080fd5b5061021e610758565b34801561040457600080fd5b5061021e610770565b34801561041957600080fd5b5061042d61042836600461267d565b61077f565b60405161022b9190612d56565b34801561044657600080fd5b5061045a6104553660046127db565b610b01565b60405161022b9190612e59565b34801561047357600080fd5b506102c561048236600461261a565b610b23565b34801561049357600080fd5b50610298610b5c565b3480156104a857600080fd5b5061021e610b8d565b3480156104bd57600080fd5b50610298610ba5565b3480156104d257600080fd5b50610298610bd4565b3480156104e757600080fd5b50610249610bff565b3480156104fc57600080fd5b506102c561050b36600461261a565b610c04565b34801561051c57600080fd5b5061021e610c31565b600080516020612f5283398151915281565b61014d81565b604081565b6060816040516020016105559190612e59565b60405160208183030381529060405290505b919050565b6001546001600160a01b0316331461058357600080fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b81525081565b600080516020612f7283398151915281565b600181565b7325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d81565b735c55b921f590a89c1ebe84df170e655a82b6212681565b6000546001600160a01b0316331461062b57600080fd5b600080516020612f728339815191526001600160a01b038316141561068957600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610683573d6000803e3d6000fd5b506106a3565b6000546106a3906001600160a01b03848116911683610c40565b5050565b6000546001600160a01b031633146106be57600080fd5b6000546001600160a01b0316ff5b6040518060400160405280601681526020017516995c9bde08195e18da185b99d9481a5b9d985b1a5960521b81525081565b7339c4a92dc506300c3ea4c67ca4ca611102ee6f2a81565b61019081565b73637726f8b08a7abe3ae3acab01a80e2d8ddef77b81565b731b14e8d511c9a4395425314f849bd737baf8208f81565b670dbd2fc137a3000081565b734ba1f38427b33b8ab7bb0490200dae1f1c36823f81565b6000546001600160a01b031681565b600060608180808080610794888a018a61280e565b9550955095509550955095506000856001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107db57600080fd5b505afa1580156107ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108139190612636565b9050336001600160a01b038216146108465760405162461bcd60e51b815260040161083d90612d74565b60405180910390fd5b816001600160a01b03168b6001600160a01b0316146108775760405162461bcd60e51b815260040161083d90612da9565b61087f612331565b61088888610b01565b9050826001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156108c357600080fd5b505afa1580156108d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fb9190612636565b6001600160a01b031660c082015261019060a08201526040516320eb73ed60e11b815273637726f8b08a7abe3ae3acab01a80e2d8ddef77b906341d6e7da90610948903290600401612bf0565b60206040518083038186803b15801561096057600080fd5b505afa158015610974573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610998919061277a565b156109a65761014d60a08201525b60008e8e60008181106109b557fe5b90506020020135905060008183604001510190508515610aad576109dd838a8a888b87610c9b565b82516001600160a01b038116600080516020612f728339815191521480610a1a57506001600160a01b038116600080516020612f52833981519152145b15610a9357600080516020612f528339815191526001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015610a6857600080fd5b505af1158015610a7c573d6000803e3d6000fd5b5050505050600080516020612f5283398151915290505b610aa76001600160a01b03821686846110b2565b50610ab9565b610ab9838a8a886110f1565b60405132904780156108fc02916000818181858888f19350505050158015610ae5573d6000803e3d6000fd5b5060019a50505050505050505050509998505050505050505050565b610b09612331565b81806020019051810190610b1d919061299d565b92915050565b6001546001600160a01b03163314610b3a57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6040518060400160405280601581526020017413d99998da185a5b8819185d18481a5b9d985b1a59605a1b81525081565b73ff40d4fb79b3b5ad3b0cc2d29d2436a488ca45ef81565b604051806040016040528060138152602001724465737420616d6f756e74206d697373696e6760681b81525081565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525081565b600281565b6000546001600160a01b03163314610c1b57600080fd5b6001546001600160a01b031615610b3a57600080fd5b6001546001600160a01b031681565b610c968363a9059cbb60e01b8484604051602401610c5f929190612d3d565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261132e565b505050565b6040860151610caa81836113bd565b60408801819052602088015188516001600160a01b03908116911614610cd757610cd3886113cd565b9150505b6000856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d1257600080fd5b505afa158015610d26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4a9190612636565b9050610dd582610dd08a6001600160a01b031663fca513a86040518163ffffffff1660e01b815260040160206040518083038186803b158015610d8c57600080fd5b505afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190612636565b858b8e602001516116f0565b6113bd565b60208a015190925047906000906001600160a01b0316600080516020612f728339815191521480610e20575060208b01516001600160a01b0316600080516020612f52833981519152145b15610e3957610e2f82856113bd565b9150839050610e52565b60208b0151610e52906001600160a01b031689866110b2565b80471015610ebe57604051632e1a7d4d60e01b8152600080516020612f5283398151915290632e1a7d4d90610e8b908490600401612ea7565b600060405180830381600087803b158015610ea557600080fd5b505af1158015610eb9573d6000803e3d6000fd5b505050505b876001600160a01b0316631cff79cd8273ff40d4fb79b3b5ad3b0cc2d29d2436a488ca45ef8d8f60200151898d8a604051602401610f00959493929190612ccd565b60408051601f198184030181529181526020820180516001600160e01b0316632c6951f360e21b1790525160e085901b6001600160e01b0319168152610f4a929190600401612cfd565b6020604051808303818588803b158015610f6357600080fd5b505af1158015610f77573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610f9c91906127c3565b50876001600160a01b0316631cff79cd73ff40d4fb79b3b5ad3b0cc2d29d2436a488ca45ef8c8e6000015189604051602401610fda93929190612c4d565b60408051601f198184030181529181526020820180516001600160e01b0316636ce5768960e11b1790525160e084901b6001600160e01b0319168152611024929190600401612cfd565b602060405180830381600087803b15801561103e57600080fd5b505af1158015611052573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107691906127c3565b506110a56040518060400160405280600b81526020016a416176655632526570617960a81b8152508c8661191e565b5050505050505050505050565b6110d28363095ea7b360e01b846000604051602401610c5f929190612d21565b610c968363095ea7b360e01b8484604051602401610c5f929190612d3d565b6040840151602085015185516001600160a01b0390811691161461111c57611118856113cd565b9150505b6111a081610dd0866001600160a01b031663fca513a86040518163ffffffff1660e01b815260040160206040518083038186803b15801561115c57600080fd5b505afa158015611170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111949190612636565b84878a602001516116f0565b60208601519091506000906001600160a01b038116600080516020612f7283398151915214806111ea575060208701516001600160a01b0316600080516020612f52833981519152145b156112075750819050600080516020612f72833981519152611220565b6020870151611220906001600160a01b031685856110b2565b836001600160a01b0316631cff79cd8373ff40d4fb79b3b5ad3b0cc2d29d2436a488ca45ef89858860405160240161125a93929190612c4d565b60408051601f198184030181529181526020820180516001600160e01b0316638340f54960e01b1790525160e085901b6001600160e01b03191681526112a4929190600401612cfd565b6020604051808303818588803b1580156112bd57600080fd5b505af11580156112d1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906112f691906127c3565b506113256040518060400160405280600b81526020016a10585d99558c909bdbdcdd60aa1b815250888561191e565b50505050505050565b6060611383826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166119c39092919063ffffffff16565b805190915015610c9657808060200190518101906113a1919061277a565b610c965760405162461bcd60e51b815260040161083d90612e0f565b80820382811115610b1d57600080fd5b6000806000806000600080516020612f728339815191526001600160a01b031686600001516001600160a01b0316141561147c57855161140c906119d2565b6001600160a01b031686526040808701518151630d0e30db60e41b81529151600080516020612f528339815191529263d0e30db09291600480830192600092919082900301818588803b15801561146257600080fd5b505af1158015611476573d6000803e3d6000fd5b50505050505b61149886604001518760c0015188600001518960a00151611a0d565b60408701805191909103905261012086015160600151156114d5576114be866000611c5a565b9250905080156114d5578561012001516020015192505b806114ef576114e5866000611e58565b91508560e0015192505b6000611508600080516020612f528339815191526120a1565b11156115e8576040516370a0823160e01b8152600080516020612f5283398151915290632e1a7d4d9082906370a0823190611547903090600401612bf0565b602060405180830381600087803b15801561156157600080fd5b505af1158015611575573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159991906127c3565b6040518263ffffffff1660e01b81526004016115b59190612ea7565b600060405180830381600087803b1580156115cf57600080fd5b505af11580156115e3573d6000803e3d6000fd5b505050505b60208601516001600160a01b0316600080516020612f52833981519152141561167f5761161d86608001518760400151612145565b611634600080516020612f728339815191526120a1565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906116795760405162461bcd60e51b815260040161083d9190612d61565b506116e5565b61169186608001518760400151612145565b61169e87602001516120a1565b10156040518060400160405280600c81526020016b14db1a5c1c1859d9481a1a5d60a21b815250906116e35760405162461bcd60e51b815260040161083d9190612d61565b505b509092509050915091565b6000826116ff57506000611916565b60006001600160a01b038316600080516020612f72833981519152146117255782611735565b600080516020612f528339815191525b90506000866001600160a01b031663b3596f07836040518263ffffffff1660e01b81526004016117659190612bf0565b60206040518083038186803b15801561177d57600080fd5b505afa158015611791573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b591906127c3565b90506117c08461217e565b601203600a0a6117d086836121e0565b816117d757fe5b049450849250600586048311156117ef576005860492505b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561183e57600080fd5b505afa158015611852573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118769190612636565b90508315611912576001600160a01b038516600080516020612f7283398151915214156118fe57806001600160a01b0316846040516118b490612bed565b60006040518083038185875af1925050503d80600081146118f1576040519150601f19603f3d011682016040523d82523d6000602084013e6118f6565b606091505b505050611912565b6119126001600160a01b0386168286610c40565b5050505b949350505050565b735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce50303386866000015187602001518860400151886040516020016119679493929190612ca4565b6040516020818303038152906040526040518563ffffffff1660e01b81526004016119959493929190612c04565b600060405180830381600087803b1580156119af57600080fd5b505af1158015611325573d6000803e3d6000fd5b60606119168484600085612200565b60006001600160a01b038216600080516020612f72833981519152146119f85781610b1d565b50600080516020612f52833981519152919050565b60008115801590611aa05750604051632cdc77ab60e21b8152731b14e8d511c9a4395425314f849bd737baf8208f9063b371deac90611a50908790600401612bf0565b60206040518083038186803b158015611a6857600080fd5b505afa158015611a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa0919061277a565b15611b2f57604051636eeb543160e01b8152731b14e8d511c9a4395425314f849bd737baf8208f90636eeb543190611adc908790600401612bf0565b60206040518083038186803b158015611af457600080fd5b505afa158015611b08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2c91906127c3565b91505b81611b3c57506000611916565b818581611b4557fe5b049050600a8504811115611b595750600a84045b60007339c4a92dc506300c3ea4c67ca4ca611102ee6f2a6001600160a01b031663b38779eb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ba857600080fd5b505afa158015611bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be09190612636565b90506001600160a01b038416600080516020612f728339815191521415611c3d576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015611c37573d6000803e3d6000fd5b50611c51565b611c516001600160a01b0385168284610c40565b50949350505050565b610120820151602001516040516302f5cc7960e11b81526000918291734ba1f38427b33b8ab7bb0490200dae1f1c36823f916305eb98f291611c9f9190600401612bf0565b60206040518083038186803b158015611cb757600080fd5b505afa158015611ccb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cef919061277a565b611cfe57506000905080611e51565b6101208401515160405163e0aa279760e01b81527325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa279791611d3b9190600401612bf0565b60206040518083038186803b158015611d5357600080fd5b505afa158015611d67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d8b919061277a565b611d9a57506000905080611e51565b6101208401515160408501518551611dbd926001600160a01b0390911691610c40565b610120840151805160809091015160405163097396a160e31b81526001600160a01b0390921691634b9cb5089190611dfb9088908890600401612e6c565b60408051808303818588803b158015611e1357600080fd5b505af1158015611e27573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e4c9190612796565b915091505b9250929050565b60e082015160405163e0aa279760e01b81526000917325dd3f51e0c3c3ff164ddc02a8e4d65bb9cbb12d9163e0aa279791611e9591600401612bf0565b60206040518083038186803b158015611ead57600080fd5b505afa158015611ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee5919061277a565b6040518060400160405280600f81526020016e15dc985c1c195c881a5b9d985b1a59608a1b81525090611f2b5760405162461bcd60e51b815260040161083d9190612d61565b5060e083015160408401518451611f4d926001600160a01b0390911691610c40565b6000826001811115611f5b57fe5b1415612001578260e001516001600160a01b0316635b6f36fc8460000151856020015186604001518761010001516040518563ffffffff1660e01b8152600401611fa89493929190612c71565b602060405180830381600087803b158015611fc257600080fd5b505af1158015611fd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ffa91906127c3565b9050610b1d565b8260e001516001600160a01b0316633924db668460000151856020015186606001518761010001516040518563ffffffff1660e01b81526004016120489493929190612c71565b602060405180830381600087803b15801561206257600080fd5b505af1158015612076573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209a91906127c3565b9392505050565b60006001600160a01b038216600080516020612f7283398151915214156120c9575047610567565b6040516370a0823160e01b81526001600160a01b038316906370a08231906120f5903090600401612bf0565b60206040518083038186803b15801561210d57600080fd5b505afa158015612121573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1d91906127c3565b6000670de0b6b3a764000061216f61215d85856122c4565b6002670de0b6b3a76400005b046122e8565b8161217657fe5b049392505050565b60006001600160a01b038216600080516020612f7283398151915214156121a757506012610567565b816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561210d57600080fd5b60008161216f6121f885670de0b6b3a76400006122c4565b600285612169565b606061220b856122f8565b6122275760405162461bcd60e51b815260040161083d90612dd8565b60006060866001600160a01b031685876040516122449190612bd1565b60006040518083038185875af1925050503d8060008114612281576040519150601f19603f3d011682016040523d82523d6000602084013e612286565b606091505b5091509150811561229a5791506119169050565b8051156122aa5780518082602001fd5b8360405162461bcd60e51b815260040161083d9190612d61565b60008115806122df575050808202828282816122dc57fe5b04145b610b1d57600080fd5b80820182811015610b1d57600080fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611916575050151592915050565b60405180610140016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016123a86123ad565b905290565b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b8035610b1d81612f2b565b8051610b1d81612f2b565b60008083601f840112612425578182fd5b50813567ffffffffffffffff81111561243c578182fd5b6020830191508360208083028501011115611e5157600080fd5b600082601f830112612466578081fd5b813561247961247482612ed7565b612eb0565b915080825283602082850101111561249057600080fd5b8060208401602084013760009082016020015292915050565b600082601f8301126124b9578081fd5b81516124c761247482612ed7565b91508082528360208285010111156124de57600080fd5b6124ef816020840160208601612efb565b5092915050565b600060c08284031215612507578081fd5b61251160c0612eb0565b9050813561251e81612f2b565b8152602082013561252e81612f2b565b6020820152604082013561254181612f2b565b80604083015250606082013560608201526080820135608082015260a082013567ffffffffffffffff81111561257657600080fd5b61258284828501612456565b60a08301525092915050565b600060c0828403121561259f578081fd5b6125a960c0612eb0565b905081516125b681612f2b565b815260208201516125c681612f2b565b602082015260408201516125d981612f2b565b80604083015250606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561260e57600080fd5b612582848285016124a9565b60006020828403121561262b578081fd5b813561209a81612f2b565b600060208284031215612647578081fd5b815161209a81612f2b565b60008060408385031215612664578081fd5b823561266f81612f2b565b946020939093013593505050565b600080600080600080600080600060a08a8c03121561269a578485fd5b893567ffffffffffffffff808211156126b1578687fd5b6126bd8d838e01612414565b909b50995060208c01359150808211156126d5578687fd5b6126e18d838e01612414565b909950975060408c01359150808211156126f9578687fd5b6127058d838e01612414565b909750955060608c0135915061271a82612f2b565b90935060808b0135908082111561272f578384fd5b818c0191508c601f830112612742578384fd5b813581811115612750578485fd5b8d6020828501011115612761578485fd5b6020830194508093505050509295985092959850929598565b60006020828403121561278b578081fd5b815161209a81612f43565b600080604083850312156127a8578182fd5b82516127b381612f43565b6020939093015192949293505050565b6000602082840312156127d4578081fd5b5051919050565b6000602082840312156127ec578081fd5b813567ffffffffffffffff811115612802578182fd5b61191684828501612456565b60008060008060008060c08789031215612826578384fd5b863567ffffffffffffffff81111561283c578485fd5b61284889828a01612456565b965050602087013561285981612f2b565b94506040870135935060608701359250608087013561287781612f43565b915060a087013561288781612f2b565b809150509295509295509295565b6000602082840312156128a6578081fd5b813567ffffffffffffffff808211156128bd578283fd5b81840191506101408083870312156128d3578384fd5b6128dc81612eb0565b90506128e886846123fe565b81526128f786602085016123fe565b602082015260408301356040820152606083013560608201526080830135608082015260a083013560a08201526129318660c085016123fe565b60c08201526129438660e085016123fe565b60e0820152610100808401358381111561295b578586fd5b61296788828701612456565b8284015250506101208084013583811115612980578586fd5b61298c888287016124f6565b918301919091525095945050505050565b6000602082840312156129ae578081fd5b815167ffffffffffffffff808211156129c5578283fd5b81840191506101408083870312156129db578384fd5b6129e481612eb0565b90506129f08684612409565b81526129ff8660208501612409565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a0820152612a398660c08501612409565b60c0820152612a4b8660e08501612409565b60e08201526101008084015183811115612a63578586fd5b612a6f888287016124a9565b8284015250506101208084015183811115612a88578586fd5b61298c8882870161258e565b6001600160a01b03169052565b60008151808452612ab9816020860160208601612efb565b601f01601f19169290920160200192915050565b6000610140612add848451612a94565b6020830151612aef6020860182612a94565b5060408301516040850152606083015160608501526080830151608085015260a083015160a085015260c0830151612b2a60c0860182612a94565b5060e0830151612b3d60e0860182612a94565b50610100808401518282870152612b5683870182612aa1565b925050506101208084015185830382870152612b728382612b7c565b9695505050505050565b600060018060a01b0380835116845280602084015116602085015280604084015116604085015250606082015160608401526080820151608084015260a082015160c060a085015261191660c0850182612aa1565b60008251612be3818460208701612efb565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b03858116825284166020820152608060408201819052600090612c3090830185612aa1565b8281036060840152612c428185612aa1565b979650505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612b7290830184612aa1565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b039586168152938516602085015260408401929092526060830152909116608082015260a00190565b6001600160a01b038316815260406020820181905260009061191690830184612aa1565b6001600160a01b0392909216825260ff16602082015260400190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b60006020825261209a6020830184612aa1565b6020808252818101527f43616c6c6261636b73206f6e6c7920616c6c6f7765642066726f6d2041617665604082015260600190565b602080825260159082015274496e69746961746f722069736e27742070726f787960581b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60006020825261209a6020830184612acd565b600060408252612e7f6040830185612acd565b905060028310612e8b57fe5b8260208301529392505050565b61ffff91909116815260200190565b90815260200190565b60405181810167ffffffffffffffff81118282101715612ecf57600080fd5b604052919050565b600067ffffffffffffffff821115612eed578081fd5b50601f01601f191660200190565b60005b83811015612f16578181015183820152602001612efe565b83811115612f25576000848401525b50505050565b6001600160a01b0381168114612f4057600080fd5b50565b8015158114612f4057600080fdfe000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeea2646970667358221220df5120c60243d86910b9ede766ef34aab2059edd91f9622bb933ff38089f105c64736f6c634300060c0033
Deployed Bytecode Sourcemap
59165:7357:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40969:81;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41135:48;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;41455:46::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;47487:134::-;;;;;;;;;;-1:-1:-1;47487:134:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;39519:122::-;;;;;;;;;;-1:-1:-1;39519:122:0;;;;;:::i;:::-;;:::i;:::-;;52617:56;;;;;;;;;;;;;:::i;47945:86::-;;;;;;;;;;;;;:::i;41510:34::-;;;;;;;;;;;;;:::i;48341:92::-;;;;;;;;;;;;;:::i;59280:85::-;;;;;;;;;;;;;:::i;39814:285::-;;;;;;;;;;-1:-1:-1;39814:285:0;;;;;:::i;:::-;;:::i;39687:80::-;;;;;;;;;;;;;:::i;52826:72::-;;;;;;;;;;;;;:::i;40769:102::-;;;;;;;;;;;;;:::i;41070:45::-;;;;;;;;;;;;;:::i;41204:89::-;;;;;;;;;;;;;:::i;40880:82::-;;;;;;;;;;;;;:::i;41383:65::-;;;;;;;;;;;;;:::i;48442:87::-;;;;;;;;;;;;;:::i;38445:20::-;;;;;;;;;;;;;:::i;64064:1921::-;;;;;;;;;;-1:-1:-1;64064:1921:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;47629:159::-;;;;;;;;;;-1:-1:-1;47629:159:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;39298:122::-;;;;;;;;;;-1:-1:-1;39298:122:0;;;;;:::i;:::-;;:::i;47828:74::-;;;;;;;;;;;;;:::i;59374:85::-;;;;;;;;;;;;;:::i;52680:70::-;;;;;;;;;;;;;:::i;52757:62::-;;;;;;;;;;;;;:::i;41551:36::-;;;;;;;;;;;;;:::i;39015:161::-;;;;;;;;;;-1:-1:-1;39015:161:0;;;;;:::i;:::-;;:::i;38472:20::-;;;;;;;;;;;;;:::i;40969:81::-;-1:-1:-1;;;;;;;;;;;40969:81:0;:::o;41135:48::-;41180:3;41135:48;:::o;41455:46::-;41499:2;41455:46;:::o;47487:134::-;47562:12;47605:7;47594:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;47587:26;;47487:134;;;;:::o;39519:122::-;39600:5;;-1:-1:-1;;;;;39600:5:0;39586:10;:19;39578:28;;;;;;39619:5;:14;;-1:-1:-1;;;;;;39619:14:0;-1:-1:-1;;;;;39619:14:0;;;;;;;;;;39519:122::o;52617:56::-;;;;;;;;;;;;;;-1:-1:-1;;;52617:56:0;;;;:::o;47945:86::-;-1:-1:-1;;;;;;;;;;;47945:86:0;:::o;41510:34::-;41543:1;41510:34;:::o;48341:92::-;48391:42;48341:92;:::o;59280:85::-;59323:42;59280:85;:::o;39814:285::-;38541:5;;-1:-1:-1;;;;;38541:5:0;38550:10;38541:19;38533:28;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;39904:52:0;::::1;;39900:192;;;39981:5;::::0;;39973:32:::1;::::0;-1:-1:-1;;;;;39981:5:0;;::::1;::::0;39973:32;::::1;;;::::0;39997:7;;39973:32;39981:5;39973:32;39997:7;39981:5;39973:32;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;39900:192;;;40065:5;::::0;40038:42:::1;::::0;-1:-1:-1;;;;;40038:26:0;;::::1;::::0;40065:5:::1;40072:7:::0;40038:26:::1;:42::i;:::-;39814:285:::0;;:::o;39687:80::-;38541:5;;-1:-1:-1;;;;;38541:5:0;38550:10;38541:19;38533:28;;;;;;39752:5:::1;::::0;-1:-1:-1;;;;;39752:5:0::1;39731:28;52826:72:::0;;;;;;;;;;;;;;-1:-1:-1;;;52826:72:0;;;;:::o;40769:102::-;40828:42;40769:102;:::o;41070:45::-;41112:3;41070:45;:::o;41204:89::-;41251:42;41204:89;:::o;40880:82::-;40920:42;40880:82;:::o;41383:65::-;41430:18;41383:65;:::o;48442:87::-;48487:42;48442:87;:::o;38445:20::-;;;-1:-1:-1;;;;;38445:20:0;;:::o;64064:1921::-;64269:4;64301:30;64269:4;;;;;64490:69;;;;64501:6;64490:69;:::i;:::-;64286:273;;;;;;;;;;;;64572:19;64626:6;-1:-1:-1;;;;;64594:54:0;;:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64572:78;-1:-1:-1;64671:10:0;-1:-1:-1;;;;;64671:25:0;;;64663:70;;;;-1:-1:-1;;;64663:70:0;;;;;;;:::i;:::-;;;;;;;;;64765:5;-1:-1:-1;;;;;64752:18:0;:9;-1:-1:-1;;;;;64752:18:0;;64744:52;;;;-1:-1:-1;;;64744:52:0;;;;;;;:::i;:::-;64809:26;;:::i;:::-;64838:37;64857:17;64838:18;:37::i;:::-;64809:66;;64907:5;-1:-1:-1;;;;;64900:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;64886:35:0;:11;;;:35;41112:3;64932:20;;;:41;64990:52;;-1:-1:-1;;;64990:52:0;;41251:42;;64990:41;;:52;;65032:9;;64990:52;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64986:129;;;41180:3;65059:20;;;:44;64986:129;65171:11;65185:8;;65194:1;65185:11;;;;;;;;;;;;;65171:25;;65207:26;65255:3;65236:6;:16;;;:22;65207:51;;65358:7;65354:546;;;65382:52;65388:6;65396;65404:7;65413:5;65420:8;65430:3;65382:5;:52::i;:::-;65467:14;;-1:-1:-1;;;;;65500:17:0;;-1:-1:-1;;;;;;;;;;;65500:17:0;;:42;;-1:-1:-1;;;;;;65521:21:0;;-1:-1:-1;;;;;;;;;;;65521:21:0;65500:42;65496:249;;;-1:-1:-1;;;;;;;;;;;;;;;;65626:36:0;;65669:18;65626:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;65709:20:0;;65496:249;65761:57;-1:-1:-1;;;;;65761:24:0;;65786:11;65799:18;65761:24;:57::i;:::-;65354:546;;;;65851:37;65857:6;65865;65873:7;65882:5;65851;:37::i;:::-;65912:41;;:9;;65931:21;65912:41;;;;;;;;;65931:21;65912:9;:41;;;;;;;;;;;;;;;;;;;;;65973:4;65966:11;;;;;;;;;;;;64064:1921;;;;;;;;;;;:::o;47629:159::-;47697:27;;:::i;:::-;47758:5;47747:33;;;;;;;;;;;;:::i;:::-;47737:43;47629:159;-1:-1:-1;;47629:159:0:o;39298:122::-;39379:5;;-1:-1:-1;;;;;39379:5:0;39365:10;:19;39357:28;;;;;;39398:5;:14;;-1:-1:-1;;;;;;39398:14:0;-1:-1:-1;;;;;39398:14:0;;;;;;;;;;39298:122::o;47828:74::-;;;;;;;;;;;;;;-1:-1:-1;;;47828:74:0;;;;:::o;59374:85::-;59417:42;59374:85;:::o;52680:70::-;;;;;;;;;;;;;;-1:-1:-1;;;52680:70:0;;;;:::o;52757:62::-;;;;;;;;;;;;;;-1:-1:-1;;;52757:62:0;;;;:::o;41551:36::-;41586:1;41551:36;:::o;39015:161::-;39096:5;;-1:-1:-1;;;;;39096:5:0;39082:10;:19;39074:28;;;;;;39121:5;;-1:-1:-1;;;;;39121:5:0;:19;39113:28;;;;;38472:20;;;-1:-1:-1;;;;;38472:20:0;;:::o;5639:176::-;5721:86;5741:5;5771:23;;;5796:2;5800:5;5748:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;5748:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;5748:58:0;-1:-1:-1;;;;;;5748:58:0;;;;;;;;;;5721:19;:86::i;:::-;5639:176;;;:::o;61098:2958::-;61435:23;;;;61558:48;61435:23;61587:18;61558:3;:48::i;:::-;61532:23;;;:74;;;61751:22;;;;61726:21;;-1:-1:-1;;;;;61726:47:0;;;;;;61722:120;;61810:20;61816:13;61810:5;:20::i;:::-;61790:40;-1:-1:-1;;61722:120:0;61854:12;61876:6;-1:-1:-1;;;;;61869:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61854:37;;61918:201;61922:13;61937:181;61994:7;-1:-1:-1;;;;;61962:55:0;;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62034:13;62062:8;62085:13;:22;;;61937:10;:181::i;:::-;61918:3;:201::i;:::-;62589:22;;;;61902:217;;-1:-1:-1;62404:21:0;;62378:23;;-1:-1:-1;;;;;62589:34:0;-1:-1:-1;;;;;;;;;;;62589:34:0;;:76;;-1:-1:-1;62627:22:0;;;;-1:-1:-1;;;;;62627:38:0;-1:-1:-1;;;;;;;;;;;62627:38:0;62589:76;62585:298;;;62700:35;62704:15;62721:13;62700:3;:35::i;:::-;62682:53;;62761:13;62750:24;;62585:298;;;62813:22;;;;62807:64;;-1:-1:-1;;;;;62807:41:0;62849:6;62857:13;62807:41;:64::i;:::-;62996:8;62972:21;:32;62968:112;;;63021:47;;-1:-1:-1;;;63021:47:0;;-1:-1:-1;;;;;;;;;;;41008:42:0;63021:37;;:47;;63059:8;;63021:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62968:112;63237:6;-1:-1:-1;;;;;63221:32:0;;63261:8;59417:42;63442:7;63468:13;:22;;;63509:13;63541:9;63569:4;63316:272;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;63316:272:0;;;;;;;;;;;;;;-1:-1:-1;;;;;63316:272:0;-1:-1:-1;;;63316:272:0;;;63221:378;;;;;-1:-1:-1;;;;;;63221:378:0;;;;;;63316:272;63221:378;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;63717:6;-1:-1:-1;;;;;63701:32:0;;59417:42;63875:7;63901:13;:21;;;63941:15;63779:192;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;63779:192:0;;;;;;;;;;;;;;-1:-1:-1;;;;;63779:192:0;-1:-1:-1;;;63779:192:0;;;63701:281;;;;;-1:-1:-1;;;;;;63701:281:0;;;;;;63779:192;63701:281;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;63995:53;;;;;;;;;;;;;;-1:-1:-1;;;63995:53:0;;;64019:13;64034;63995:8;:53::i;:::-;61098:2958;;;;;;;;;;;:::o;6188:281::-;6274:86;6294:5;6324:22;;;6348:7;6357:1;6301:58;;;;;;;;;:::i;6274:86::-;6371:90;6391:5;6421:22;;;6445:7;6454:5;6398:62;;;;;;;;;:::i;59468:1622::-;59656:23;;;;59757:22;;;;59732:21;;-1:-1:-1;;;;;59732:47:0;;;;;;59728:120;;59816:20;59822:13;59816:5;:20::i;:::-;59796:40;-1:-1:-1;;59728:120:0;59876:201;59880:13;59895:181;59952:7;-1:-1:-1;;;;;59920:55:0;;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59992:13;60020:8;60043:13;:22;;;59895:10;:181::i;59876:201::-;60253:22;;;;59860:217;;-1:-1:-1;60206:16:0;;-1:-1:-1;;;;;60421:34:0;;-1:-1:-1;;;;;;;;;;;60421:34:0;;:76;;-1:-1:-1;60459:22:0;;;;-1:-1:-1;;;;;60459:38:0;-1:-1:-1;;;;;;;;;;;60459:38:0;60421:76;60417:261;;;-1:-1:-1;60525:13:0;;-1:-1:-1;;;;;;;;;;;;60417:261:0;;;60608:22;;;;60602:64;;-1:-1:-1;;;;;60602:41:0;60644:6;60652:13;60602:41;:64::i;:::-;60753:6;-1:-1:-1;;;;;60737:32:0;;60777:8;59417:42;60927:7;60953:5;60977:13;60832:173;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;60832:173:0;;;;;;;;;;;;;;-1:-1:-1;;;;;60832:173:0;-1:-1:-1;;;60832:173:0;;;60737:279;;;;;-1:-1:-1;;;;;;60737:279:0;;;;;;60832:173;60737:279;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;61029:53;;;;;;;;;;;;;;-1:-1:-1;;;61029:53:0;;;61053:13;61068;61029:8;:53::i;:::-;59468:1622;;;;;;;:::o;7108:419::-;7190:23;7216:69;7244:4;7216:69;;;;;;;;;;;;;;;;;7224:5;-1:-1:-1;;;;;7216:27:0;;;:69;;;;;:::i;:::-;7300:17;;7190:95;;-1:-1:-1;7300:21:0;7296:224;;7442:10;7431:30;;;;;;;;;;;;:::i;:::-;7423:85;;;;-1:-1:-1;;;7423:85:0;;;;;;;:::i;11444:113::-;11537:5;;;11532:16;;;;11524:25;;;;;53169:1670;53230:7;53239:4;53258:15;53284:17;53312:12;-1:-1:-1;;;;;;;;;;;;;;;;53385:35:0;:6;:14;;;-1:-1:-1;;;;;53385:35:0;;53381:201;;;53468:14;;53454:29;;:13;:29::i;:::-;-1:-1:-1;;;;;53437:46:0;;;53551:16;;;;;53498:72;;-1:-1:-1;;;53498:72:0;;;;-1:-1:-1;;;;;;;;;;;48086:42:0;53498:45;;53551:16;53498:72;;;;;53437:14;;53498:72;;;;;;;53551:16;48086:42;53498:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53381:201;53614:75;53621:6;:16;;;53639:6;:11;;;53652:6;:14;;;53668:6;:20;;;53614:6;:75::i;:::-;53594:16;;;:95;;;;;;;;53769:19;;;;:25;;;:29;53765:228;;53841:34;53851:6;53859:15;53841:9;:34::i;:::-;53815:60;-1:-1:-1;53815:60:0;-1:-1:-1;53892:90:0;;;;53934:6;:19;;;:32;;;53924:42;;53892:90;54063:7;54058:129;;54102:34;54112:6;54120:15;54102:9;:34::i;:::-;54087:49;;54161:6;:14;;;54151:24;;54058:129;54303:1;54267:33;-1:-1:-1;;;;;;;;;;;54267:10:0;:33::i;:::-;:37;54263:212;;;54386:62;;-1:-1:-1;;;54386:62:0;;-1:-1:-1;;;;;;;;;;;48086:42:0;54321:46;;48086:42;;54386:47;;:62;;54442:4;;54386:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54321:142;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54263:212;54491:15;;;;-1:-1:-1;;;;;54491:40:0;-1:-1:-1;;;;;;;;;;;54491:40:0;54487:302;;;54589:39;54594:6;:15;;;54611:6;:16;;;54589:4;:39::i;:::-;54556:29;-1:-1:-1;;;;;;;;;;;54556:10:0;:29::i;:::-;:72;;54630:16;;;;;;;;;;;;;-1:-1:-1;;;54630:16:0;;;54548:99;;;;;-1:-1:-1;;;54548:99:0;;;;;;;;:::i;:::-;;54487:302;;;54719:39;54724:6;:15;;;54741:6;:16;;;54719:4;:39::i;:::-;54688:27;54699:6;:15;;;54688:10;:27::i;:::-;:70;;54760:16;;;;;;;;;;;;;-1:-1:-1;;;54760:16:0;;;54680:97;;;;;-1:-1:-1;;;54680:97:0;;;;;;;;:::i;:::-;;54487:302;-1:-1:-1;54809:7:0;;-1:-1:-1;54818:12:0;-1:-1:-1;53169:1670:0;;;:::o;41960:1059::-;42071:12;42100:13;42096:27;;-1:-1:-1;42122:1:0;42115:8;;42096:27;42283:18;-1:-1:-1;;;;;42304:22:0;;-1:-1:-1;;;;;;;;;;;42304:22:0;:50;;42344:10;42304:50;;;-1:-1:-1;;;;;;;;;;;42304:50:0;42283:71;;42365:13;42404:14;-1:-1:-1;;;;;42381:52:0;;42434:10;42381:64;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42365:80;;42504:24;42517:10;42504:12;:24::i;:::-;42499:2;:29;42492:2;:37;42467:21;42472:8;42482:5;42467:4;:21::i;:::-;:63;;;;;;;-1:-1:-1;42467:63:0;;-1:-1:-1;42656:1:0;42646:7;:11;42635:7;:23;42631:77;;;42695:1;42685:7;:11;42675:21;;42631:77;42720:18;40828:42;-1:-1:-1;;;;;42741:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42720:46;-1:-1:-1;42783:11:0;;42779:233;;-1:-1:-1;;;;;42815:22:0;;-1:-1:-1;;;;;;;;;;;42815:22:0;42811:190;;;42858:10;-1:-1:-1;;;;;42858:15:0;42881:7;42858:35;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42811:190;;;42934:51;-1:-1:-1;;;;;42934:30:0;;42965:10;42977:7;42934:30;:51::i;:::-;41960:1059;;;;;;;;;;:::o;66062:357::-;59323:42;-1:-1:-1;;;;;66177:37:0;;66237:4;66257:10;66282:5;66313:13;:21;;;66336:13;:22;;;66360:13;:23;;;66385:14;66302:98;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;66177:234;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2032:196;2135:12;2167:53;2190:6;2198:4;2204:1;2207:12;2167:22;:53::i;51515:151::-;51575:7;-1:-1:-1;;;;;51602:25:0;;-1:-1:-1;;;;;;;;;;;51602:25:0;:56;;51654:4;51602:56;;;-1:-1:-1;;;;;;;;;;;;48086:42:0;51515:151;-1:-1:-1;51515:151:0:o;49829:905::-;49935:17;49969:19;;;;;:71;;-1:-1:-1;49992:48:0;;-1:-1:-1;;;49992:48:0;;48292:42;;49992:41;;:48;;50034:5;;49992:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49965:174;;;50074:53;;-1:-1:-1;;;50074:53:0;;48292:42;;50074:46;;:53;;50121:5;;50074:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50057:70;;49965:174;50155:19;50151:576;;-1:-1:-1;50203:1:0;50151:576;;;50259:14;50249:7;:24;;;;;;;-1:-1:-1;50375:2:0;50365:7;:12;50352:9;:26;50348:91;;;-1:-1:-1;50421:2:0;50411:12;;50348:91;50455:18;48197:42;-1:-1:-1;;;;;50476:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50455:47;-1:-1:-1;;;;;;50523:27:0;;-1:-1:-1;;;;;;;;;;;50523:27:0;50519:197;;;50571:39;;-1:-1:-1;;;;;50571:28:0;;;:39;;;;;50600:9;;50571:39;;;;50600:9;50571:28;:39;;;;;;;;;;;;;;;;;;;;;50519:197;;;50651:49;-1:-1:-1;;;;;50651:26:0;;50678:10;50690:9;50651:26;:49::i;:::-;50151:576;49829:905;;;;;;:::o;56882:692::-;57072:20;;;;:33;;;57029:77;;-1:-1:-1;;;57029:77:0;;56990:12;;;;48487:42;;57029;;:77;;57072:33;57029:77;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57024:128;;-1:-1:-1;57131:5:0;;-1:-1:-1;57131:5:0;57123:17;;57024:128;57226:20;;;;:28;57169:86;;-1:-1:-1;;;57169:86:0;;48391:42;;57169:56;;:86;;57226:28;57169:86;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57164:137;;-1:-1:-1;57280:5:0;;-1:-1:-1;57280:5:0;57272:17;;57164:137;57377:20;;;;:28;57407:17;;;;57347:15;;57341:84;;-1:-1:-1;;;;;57341:35:0;;;;;:84::i;:::-;57470:20;;;;:28;;57517:32;;;;;57445:121;;-1:-1:-1;;;57445:121:0;;-1:-1:-1;;;;;57445:64:0;;;;;;57517:32;57445:121;;57470:7;;57560:5;;57445:121;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57438:128;;;;56882:692;;;;;;:::o;57840:717::-;58019:15;;;;57962:73;;-1:-1:-1;;;57962:73:0;;57924:17;;48391:42;;57962:56;;:73;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58037:19;;;;;;;;;;;;;-1:-1:-1;;;58037:19:0;;;57954:103;;;;;-1:-1:-1;;;57954:103:0;;;;;;;;:::i;:::-;-1:-1:-1;58106:15:0;;;;58123:17;;;;58076:15;;58070:71;;-1:-1:-1;;;;;58070:35:0;;;;;:71::i;:::-;58167:15;58158:5;:24;;;;;;;;;58154:396;;;58234:7;:15;;;-1:-1:-1;;;;;58214:63:0;;58278:7;:15;;;58295:7;:16;;;58313:7;:17;;;58332:7;:19;;;58214:138;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58199:153;;58154:396;;;58420:7;:15;;;-1:-1:-1;;;;;58400:62:0;;58463:7;:15;;;58480:7;:16;;;58498:7;:18;;;58518:7;:19;;;58400:138;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58385:153;57840:717;-1:-1:-1;;;57840:717:0:o;48722:275::-;48785:12;-1:-1:-1;;;;;48814:31:0;;-1:-1:-1;;;;;;;;;;;48814:31:0;48810:180;;;-1:-1:-1;48872:21:0;48810:180;;;48936:42;;-1:-1:-1;;;48936:42:0;;-1:-1:-1;;;;;48936:27:0;;;;;:42;;48972:4;;48936:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;12346:122::-;12405:9;12295:6;12431:23;12435:9;12439:1;12442;12435:3;:9::i;:::-;12452:1;12295:6;12446:7;;12431:3;:23::i;:::-;:29;;;;;;;12346:122;-1:-1:-1;;;12346:122:0:o;44514:166::-;44575:7;-1:-1:-1;;;;;44599:18:0;;-1:-1:-1;;;;;;;;;;;44599:18:0;44595:33;;;-1:-1:-1;44626:2:0;44619:9;;44595:33;44654:6;-1:-1:-1;;;;;44648:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12606:120;12665:9;12717:1;12691:23;12695:11;12699:1;12295:6;12695:3;:11::i;:::-;12712:1;12708;:5;;2794:979;2924:12;2957:18;2968:6;2957:10;:18::i;:::-;2949:60;;;;-1:-1:-1;;;2949:60:0;;;;;;;:::i;:::-;3083:12;3097:23;3124:6;-1:-1:-1;;;;;3124:11:0;3144:8;3155:4;3124:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3082:78;;;;3175:7;3171:595;;;3206:10;-1:-1:-1;3199:17:0;;-1:-1:-1;3199:17:0;3171:595;3320:17;;:21;3316:439;;3583:10;3577:17;3644:15;3631:10;3627:2;3623:19;3616:44;3531:148;3726:12;3719:20;;-1:-1:-1;;;3719:20:0;;;;;;;;:::i;11565:127::-;11623:9;11653:6;;;:30;;-1:-1:-1;;11668:5:0;;;11682:1;11677;11668:5;11677:1;11663:15;;;;;:20;11653:30;11645:39;;;;;11323:113;11416:5;;;11411:16;;;;11403:25;;;;;819:619;879:4;1347:20;;1190:66;1387:23;;;;;;:42;;-1:-1:-1;;1414:15:0;;;1379:51;-1:-1:-1;;819:619:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130::-;72:20;;97:33;72:20;97:33;:::i;142:134::-;220:13;;238:33;220:13;238:33;:::i;454:352::-;;;584:3;577:4;569:6;565:17;561:27;551:2;;-1:-1;;592:12;551:2;-1:-1;622:20;;662:18;651:30;;648:2;;;-1:-1;;684:12;648:2;728:4;720:6;716:17;704:29;;779:3;728:4;;763:6;759:17;720:6;745:32;;742:41;739:2;;;796:1;;786:12;1958:440;;2059:3;2052:4;2044:6;2040:17;2036:27;2026:2;;-1:-1;;2067:12;2026:2;2114:6;2101:20;2136:64;2151:48;2192:6;2151:48;:::i;:::-;2136:64;:::i;:::-;2127:73;;2220:6;2213:5;2206:21;2324:3;2256:4;2315:6;2248;2306:16;;2303:25;2300:2;;;2341:1;;2331:12;2300:2;36053:6;2256:4;2248:6;2244:17;2256:4;2282:5;2278:16;36030:30;36109:1;36091:16;;;2256:4;36091:16;36084:27;2282:5;2019:379;-1:-1;;2019:379::o;2407:442::-;;2519:3;2512:4;2504:6;2500:17;2496:27;2486:2;;-1:-1;;2527:12;2486:2;2567:6;2561:13;2589:64;2604:48;2645:6;2604:48;:::i;2589:64::-;2580:73;;2673:6;2666:5;2659:21;2777:3;2709:4;2768:6;2701;2759:16;;2756:25;2753:2;;;2794:1;;2784:12;2753:2;2804:39;2836:6;2709:4;2735:5;2731:16;2709:4;2701:6;2697:17;2804:39;:::i;:::-;;2479:370;;;;:::o;6900:1179::-;;7019:4;7007:9;7002:3;6998:19;6994:30;6991:2;;;-1:-1;;7027:12;6991:2;7055:20;7019:4;7055:20;:::i;:::-;7046:29;;85:6;72:20;97:33;124:5;97:33;:::i;:::-;7135:75;;7279:2;7333:22;;72:20;97:33;72:20;97:33;:::i;:::-;7279:2;7294:16;;7287:75;7434:2;7488:22;;72:20;97:33;72:20;97:33;:::i;:::-;7467:49;7434:2;7453:5;7449:16;7442:75;;7579:2;7637:9;7633:22;9451:20;7579:2;7598:5;7594:16;7587:75;7730:3;7789:9;7785:22;9451:20;7730:3;7750:5;7746:16;7739:75;7907:3;7896:9;7892:19;7879:33;7932:18;7924:6;7921:30;7918:2;;;-1:-1;;7954:12;7918:2;7999:58;8053:3;8044:6;8033:9;8029:22;7999:58;:::i;:::-;7907:3;7985:5;7981:16;7974:84;;6985:1094;;;;:::o;8128:1249::-;;8258:4;8246:9;8241:3;8237:19;8233:30;8230:2;;;-1:-1;;8266:12;8230:2;8294:20;8258:4;8294:20;:::i;:::-;8285:29;;226:6;220:13;238:33;265:5;238:33;:::i;:::-;8374:86;;8529:2;8594:22;;220:13;238:33;220:13;238:33;:::i;:::-;8529:2;8544:16;;8537:86;8695:2;8760:22;;220:13;238:33;220:13;238:33;:::i;:::-;8728:60;8695:2;8714:5;8710:16;8703:86;;8851:2;8920:9;8916:22;9599:13;8851:2;8870:5;8866:16;8859:86;9013:3;9083:9;9079:22;9599:13;9013:3;9033:5;9029:16;9022:86;9194:3;9183:9;9179:19;9173:26;9219:18;9211:6;9208:30;9205:2;;;-1:-1;;9241:12;9205:2;9286:69;9351:3;9342:6;9331:9;9327:22;9286:69;:::i;9662:241::-;;9766:2;9754:9;9745:7;9741:23;9737:32;9734:2;;;-1:-1;;9772:12;9734:2;85:6;72:20;97:33;124:5;97:33;:::i;9910:263::-;;10025:2;10013:9;10004:7;10000:23;9996:32;9993:2;;;-1:-1;;10031:12;9993:2;226:6;220:13;238:33;265:5;238:33;:::i;10180:366::-;;;10301:2;10289:9;10280:7;10276:23;10272:32;10269:2;;;-1:-1;;10307:12;10269:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;10359:63;10459:2;10498:22;;;;9451:20;;-1:-1;;;10263:283::o;10553:1335::-;;;;;;;;;;10849:3;10837:9;10828:7;10824:23;10820:33;10817:2;;;-1:-1;;10856:12;10817:2;10914:17;10901:31;10952:18;;10944:6;10941:30;10938:2;;;-1:-1;;10974:12;10938:2;11012:80;11084:7;11075:6;11064:9;11060:22;11012:80;:::i;:::-;10994:98;;-1:-1;10994:98;-1:-1;11157:2;11142:18;;11129:32;;-1:-1;11170:30;;;11167:2;;;-1:-1;;11203:12;11167:2;11241:80;11313:7;11304:6;11293:9;11289:22;11241:80;:::i;:::-;11223:98;;-1:-1;11223:98;-1:-1;11386:2;11371:18;;11358:32;;-1:-1;11399:30;;;11396:2;;;-1:-1;;11432:12;11396:2;11470:80;11542:7;11533:6;11522:9;11518:22;11470:80;:::i;:::-;11452:98;;-1:-1;11452:98;-1:-1;11587:2;11626:22;;72:20;;-1:-1;97:33;72:20;97:33;:::i;:::-;11595:63;;-1:-1;11723:3;11708:19;;11695:33;;11737:30;;;11734:2;;;-1:-1;;11770:12;11734:2;11855:6;11844:9;11840:22;;;1727:3;1720:4;1712:6;1708:17;1704:27;1694:2;;-1:-1;;1735:12;1694:2;1778:6;1765:20;10952:18;1797:6;1794:30;1791:2;;;-1:-1;;1827:12;1791:2;1922:3;11157:2;1902:17;1863:6;1888:32;;1885:41;1882:2;;;-1:-1;;1929:12;1882:2;11157;1863:6;1859:17;11790:82;;;;;;;;10811:1077;;;;;;;;;;;:::o;11895:257::-;;12007:2;11995:9;11986:7;11982:23;11978:32;11975:2;;;-1:-1;;12013:12;11975:2;1404:6;1398:13;1416:30;1440:5;1416:30;:::i;12159:393::-;;;12288:2;12276:9;12267:7;12263:23;12259:32;12256:2;;;-1:-1;;12294:12;12256:2;1404:6;1398:13;1416:30;1440:5;1416:30;:::i;:::-;12454:2;12504:22;;;;9599:13;12346:71;;9599:13;;-1:-1;;;12250:302::o;12559:263::-;;12674:2;12662:9;12653:7;12649:23;12645:32;12642:2;;;-1:-1;;12680:12;12642:2;-1:-1;1536:13;;12636:186;-1:-1;12636:186::o;12829:345::-;;12942:2;12930:9;12921:7;12917:23;12913:32;12910:2;;;-1:-1;;12948:12;12910:2;13006:17;12993:31;13044:18;13036:6;13033:30;13030:2;;;-1:-1;;13066:12;13030:2;13096:62;13150:7;13141:6;13130:9;13126:22;13096:62;:::i;13181:999::-;;;;;;;13392:3;13380:9;13371:7;13367:23;13363:33;13360:2;;;-1:-1;;13399:12;13360:2;13457:17;13444:31;13495:18;13487:6;13484:30;13481:2;;;-1:-1;;13517:12;13481:2;13547:62;13601:7;13592:6;13581:9;13577:22;13547:62;:::i;:::-;13537:72;;;13646:2;13697:9;13693:22;358:20;383:41;418:5;383:41;:::i;:::-;13654:71;-1:-1;13762:2;13801:22;;9451:20;;-1:-1;13870:2;13909:22;;9451:20;;-1:-1;13978:3;14015:22;;1256:20;1281:30;1256:20;1281:30;:::i;:::-;13987:60;-1:-1;14084:3;14132:22;;358:20;383:41;358:20;383:41;:::i;:::-;14093:71;;;;13354:826;;;;;;;;:::o;14187:387::-;;14321:2;14309:9;14300:7;14296:23;14292:32;14289:2;;;-1:-1;;14327:12;14289:2;14385:17;14372:31;14423:18;;14415:6;14412:30;14409:2;;;-1:-1;;14445:12;14409:2;14541:6;14530:9;14526:22;;;3018:6;;3006:9;3001:3;2997:19;2993:32;2990:2;;;-1:-1;;3028:12;2990:2;3056:22;3018:6;3056:22;:::i;:::-;3047:31;;3163:49;3208:3;3184:22;3163:49;:::i;:::-;3145:16;3138:75;3311:49;3356:3;14321:2;3336:9;3332:22;3311:49;:::i;:::-;14321:2;3297:5;3293:16;3286:75;3427:2;3485:9;3481:22;9451:20;3427:2;3446:5;3442:16;3435:75;3577:2;3635:9;3631:22;9451:20;3577:2;3596:5;3592:16;3585:75;3725:3;3784:9;3780:22;9451:20;3725:3;3745:5;3741:16;3734:75;3879:3;3938:9;3934:22;9451:20;3879:3;3899:5;3895:16;3888:75;4058:49;4103:3;4024;4083:9;4079:22;4058:49;:::i;:::-;4024:3;4044:5;4040:16;4033:75;4206:49;4251:3;4172;4231:9;4227:22;4206:49;:::i;:::-;4172:3;4192:5;4188:16;4181:75;4352:3;;4341:9;4337:19;4324:33;14423:18;4369:6;4366:30;4363:2;;;-1:-1;;4399:12;4363:2;4446:58;4500:3;4491:6;4480:9;4476:22;4446:58;:::i;:::-;4352:3;4430:5;4426:18;4419:86;;;4602:3;;4591:9;4587:19;4574:33;14423:18;4619:6;4616:30;4613:2;;;-1:-1;;4649:12;4613:2;4696:79;4771:3;4762:6;4751:9;4747:22;4696:79;:::i;:::-;4676:18;;;4669:107;;;;-1:-1;4680:5;14283:291;-1:-1;;;;;14283:291::o;14581:402::-;;14726:2;14714:9;14705:7;14701:23;14697:32;14694:2;;;-1:-1;;14732:12;14694:2;14783:17;14777:24;14821:18;;14813:6;14810:30;14807:2;;;-1:-1;;14843:12;14807:2;14950:6;14939:9;14935:22;;;4976:6;;4964:9;4959:3;4955:19;4951:32;4948:2;;;-1:-1;;4986:12;4948:2;5014:22;4976:6;5014:22;:::i;:::-;5005:31;;5121:60;5177:3;5153:22;5121:60;:::i;:::-;5103:16;5096:86;5280:60;5336:3;14726:2;5316:9;5312:22;5280:60;:::i;:::-;14726:2;5266:5;5262:16;5255:86;5407:2;5476:9;5472:22;9599:13;5407:2;5426:5;5422:16;5415:86;5568:2;5637:9;5633:22;9599:13;5568:2;5587:5;5583:16;5576:86;5727:3;5797:9;5793:22;9599:13;5727:3;5747:5;5743:16;5736:86;5892:3;5962:9;5958:22;9599:13;5892:3;5912:5;5908:16;5901:86;6082:60;6138:3;6048;6118:9;6114:22;6082:60;:::i;:::-;6048:3;6068:5;6064:16;6057:86;6241:60;6297:3;6207;6277:9;6273:22;6241:60;:::i;:::-;6207:3;6227:5;6223:16;6216:86;6391:3;;6380:9;6376:19;6370:26;14821:18;6408:6;6405:30;6402:2;;;-1:-1;;6438:12;6402:2;6485:69;6550:3;6541:6;6530:9;6526:22;6485:69;:::i;:::-;6391:3;6469:5;6465:18;6458:97;;;6645:3;;6634:9;6630:19;6624:26;14821:18;6662:6;6659:30;6656:2;;;-1:-1;;6692:12;6656:2;6739:90;6825:3;6816:6;6805:9;6801:22;6739:90;:::i;15409:103::-;-1:-1;;;;;34788:54;15470:37;;15464:48::o;15750:323::-;;15882:5;33290:12;33565:6;33560:3;33553:19;15965:52;16010:6;33602:4;33597:3;33593:14;33602:4;15991:5;15987:16;15965:52;:::i;:::-;36486:7;36470:14;-1:-1;;36466:28;16029:39;;;;33602:4;16029:39;;15830:243;-1:-1;;15830:243::o;19411:1986::-;;19572:6;19672:63;19720:14;19649:16;19643:23;19672:63;:::i;:::-;19818:4;19811:5;19807:16;19801:23;19830:63;19818:4;19882:3;19878:14;19864:12;19830:63;:::i;:::-;;19977:4;19970:5;19966:16;19960:23;19977:4;20041:3;20037:14;22889:37;20137:4;20130:5;20126:16;20120:23;20137:4;20201:3;20197:14;22889:37;20295:4;20288:5;20284:16;20278:23;20295:4;20359:3;20355:14;22889:37;20458:4;20451:5;20447:16;20441:23;20458:4;20522:3;20518:14;22889:37;20612:4;20605:5;20601:16;20595:23;20624:63;20612:4;20676:3;20672:14;20658:12;20624:63;:::i;:::-;;20769:4;20762:5;20758:16;20752:23;20781:63;20769:4;20833:3;20829:14;20815:12;20781:63;:::i;:::-;;20930:6;;20923:5;20919:18;20913:25;19572:6;20930;20962:3;20958:16;20951:40;21006:71;19572:6;19567:3;19563:16;21058:12;21006:71;:::i;:::-;20998:79;;;;21170:6;;21163:5;21159:18;21153:25;21226:3;21220:4;21216:14;21170:6;21202:3;21198:16;21191:40;21246:113;21354:4;21340:12;21246:113;:::i;:::-;21381:11;19545:1852;-1:-1;;;;;;19545:1852::o;21485:1219::-;;662:18;;34799:42;;;;21711:16;21705:23;34788:54;15477:3;15470:37;34799:42;21884:4;21877:5;21873:16;21867:23;34788:54;21884:4;21948:3;21944:14;15470:37;34799:42;22049:4;22042:5;22038:16;22032:23;34788:54;22049:4;22113:3;22109:14;15470:37;;22204:4;22197:5;22193:16;22187:23;22204:4;22268:3;22264:14;22889:37;22365:4;22358:5;22354:16;22348:23;22365:4;22429:3;22425:14;22889:37;22523:4;22516:5;22512:16;22506:23;21636:4;22523;22553:3;22549:14;22542:38;22595:71;21636:4;21631:3;21627:14;22647:12;22595:71;:::i;23058:271::-;;16590:5;33290:12;16701:52;16746:6;16741:3;16734:4;16727:5;16723:16;16701:52;:::i;:::-;16765:16;;;;;23192:137;-1:-1;;23192:137::o;23336:379::-;23700:10;23524:191::o;23722:222::-;-1:-1;;;;;34788:54;;;;15470:37;;23849:2;23834:18;;23820:124::o;24196:760::-;-1:-1;;;;;34788:54;;;15339:58;;34788:54;;24642:2;24627:18;;15339:58;24461:3;24679:2;24664:18;;24657:48;;;24196:760;;24719:78;;24446:19;;24783:6;24719:78;:::i;:::-;24845:9;24839:4;24835:20;24830:2;24819:9;24815:18;24808:48;24870:76;24941:4;24932:6;24870:76;:::i;:::-;24862:84;24432:524;-1:-1;;;;;;;24432:524::o;24963:444::-;-1:-1;;;;;34788:54;;;15470:37;;34788:54;;;;25310:2;25295:18;;15470:37;25393:2;25378:18;;22889:37;;;;25146:2;25131:18;;25117:290::o;25414:640::-;-1:-1;;;;;34788:54;;;15470:37;;34788:54;;25808:2;25793:18;;15470:37;25891:2;25876:18;;22889:37;;;25643:3;25928:2;25913:18;;25906:48;;;25414:640;;25968:76;;25628:19;;26030:6;25968:76;:::i;26061:556::-;-1:-1;;;;;34788:54;;;15470:37;;34788:54;;;;26437:2;26422:18;;15470:37;26520:2;26505:18;;22889:37;26603:2;26588:18;;22889:37;;;;26272:3;26257:19;;26243:374::o;26624:668::-;-1:-1;;;;;34788:54;;;15470:37;;34788:54;;;27028:2;27013:18;;15470:37;27111:2;27096:18;;22889:37;;;;27194:2;27179:18;;22889:37;34788:54;;;27277:3;27262:19;;15470:37;26863:3;26848:19;;26834:458::o;27299:417::-;-1:-1;;;;;34788:54;;15470:37;;27472:2;27590;27575:18;;27568:48;;;27299:417;;27630:76;;27457:18;;27692:6;27630:76;:::i;27723:345::-;-1:-1;;;;;34788:54;;;;15470:37;;35004:4;34993:16;28054:2;28039:18;;17206:56;27884:2;27869:18;;27855:213::o;28075:333::-;-1:-1;;;;;34788:54;;;;15470:37;;28394:2;28379:18;;22889:37;28230:2;28215:18;;28201:207::o;28415:210::-;34387:13;;34380:21;15704:34;;28536:2;28521:18;;28507:118::o;28632:306::-;;28777:2;28798:17;28791:47;28852:76;28777:2;28766:9;28762:18;28914:6;28852:76;:::i;29535:416::-;29735:2;29749:47;;;29720:18;;;33553:19;17889:34;33593:14;;;17869:55;17943:12;;;29706:245::o;29958:416::-;30158:2;30172:47;;;18194:2;30143:18;;;33553:19;-1:-1;;;33593:14;;;18210:44;18273:12;;;30129:245::o;30381:416::-;30581:2;30595:47;;;18829:2;30566:18;;;33553:19;18865:31;33593:14;;;18845:52;18916:12;;;30552:245::o;30804:416::-;31004:2;31018:47;;;19167:2;30989:18;;;33553:19;19203:34;33593:14;;;19183:55;-1:-1;;;19258:12;;;19251:34;19304:12;;;30975:245::o;31227:390::-;;31414:2;31435:17;31428:47;31489:118;31414:2;31403:9;31399:18;31593:6;31489:118;:::i;31624:527::-;;31852:2;31873:17;31866:47;31927:118;31852:2;31841:9;31837:18;32031:6;31927:118;:::i;:::-;31919:126;;36591:1;36584:5;36581:12;36571:2;;36597:9;36571:2;35558:39;32137:2;32126:9;32122:18;17054:63;31823:328;;;;;:::o;32158:218::-;34707:6;34696:18;;;;22780:36;;32283:2;32268:18;;32254:122::o;32383:222::-;22889:37;;;32510:2;32495:18;;32481:124::o;32612:256::-;32674:2;32668:9;32700:17;;;32775:18;32760:34;;32796:22;;;32757:62;32754:2;;;32832:1;;32822:12;32754:2;32674;32841:22;32652:216;;-1:-1;32652:216::o;32875:321::-;;33018:18;33010:6;33007:30;33004:2;;;-1:-1;;33040:12;33004:2;-1:-1;36486:7;33094:17;-1:-1;;33090:33;33181:4;33171:15;;32941:255::o;36126:268::-;36191:1;36198:101;36212:6;36209:1;36206:13;36198:101;;;36279:11;;;36273:18;36260:11;;;36253:39;36234:2;36227:10;36198:101;;;36314:6;36311:1;36308:13;36305:2;;;36191:1;36370:6;36365:3;36361:16;36354:27;36305:2;;36175:219;;;:::o;36620:117::-;-1:-1;;;;;34788:54;;36679:35;;36669:2;;36728:1;;36718:12;36669:2;36663:74;:::o;36884:111::-;36965:5;34387:13;34380:21;36943:5;36940:32;36930:2;;36986:1;;36976:12
Swarm Source
ipfs://df5120c60243d86910b9ede766ef34aab2059edd91f9622bb933ff38089f105c
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.