More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
_transfer Admin | 11873584 | 1445 days ago | IN | 0 ETH | 0.00277203 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
BalanceSheet
Compiler Version
v0.7.6+commit.7338295f
Contract Source Code (Solidity Multiple files format)
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; import "./Admin.sol"; import "./Exponential.sol"; import "./Erc20Interface.sol"; import "./SafeErc20.sol"; import "./ReentrancyGuard.sol"; import "./BalanceSheetInterface.sol"; import "./FintrollerInterface.sol"; import "./FyTokenInterface.sol"; import "./ChainlinkOperatorInterface.sol"; /** * @title BalanceSheet * @author Hifi * @notice Manages the debt vault for all fyTokens. */ contract BalanceSheet is ReentrancyGuard, /* no depedency */ BalanceSheetInterface, /* one dependency */ Admin, /* two dependencies */ Exponential /* two dependencies */ { using SafeErc20 for Erc20Interface; modifier isVaultOpenForMsgSender(FyTokenInterface fyToken) { require(vaults[address(fyToken)][msg.sender].isOpen, "ERR_VAULT_NOT_OPEN"); _; } /** * @param fintroller_ The address of the Fintroller contract. */ constructor(FintrollerInterface fintroller_) Admin() { /* Set the fyToken contract and sanity check it. */ fintroller = fintroller_; fintroller.isFintroller(); } /** * CONSTANT FUNCTIONS */ struct GetClutchableCollateralLocalVars { MathError mathErr; Exp clutchableCollateralAmountUpscaled; uint256 clutchableCollateralAmount; uint256 collateralPrecisionScalar; uint256 collateralPriceUpscaled; uint256 liquidationIncentiveMantissa; Exp numerator; uint256 oraclePricePrecisionScalar; uint256 underlyingPriceUpscaled; } /** * @notice Determines the amount of collateral that can be clutched when liquidating a borrow. * * @dev The formula applied: * clutchedCollateral = repayAmount * liquidationIncentive * underlyingPriceUsd / collateralPriceUsd * * Requirements: * * - `repayAmount` must be non-zero. * * @param fyToken The fyToken to make the query against. * @param repayAmount The amount of fyTokens to repay. * @return The amount of clutchable collateral as uint256, specified in the collateral's decimal system. */ function getClutchableCollateral(FyTokenInterface fyToken, uint256 repayAmount) external view override returns (uint256) { GetClutchableCollateralLocalVars memory vars; /* Avoid the zero edge cases. */ require(repayAmount > 0, "ERR_GET_CLUTCHABLE_COLLATERAL_ZERO"); /* When the liquidation incentive is zero, the end result would be zero anyways. */ vars.liquidationIncentiveMantissa = fintroller.liquidationIncentiveMantissa(); if (vars.liquidationIncentiveMantissa == 0) { return 0; } /* Grab the upscaled USD price of the underlying. */ ChainlinkOperatorInterface oracle = fintroller.oracle(); vars.underlyingPriceUpscaled = oracle.getAdjustedPrice(fyToken.underlying().symbol()); /* Grab the upscaled USD price of the collateral. */ vars.collateralPriceUpscaled = oracle.getAdjustedPrice(fyToken.collateral().symbol()); /* Calculate the top part of the equation. */ (vars.mathErr, vars.numerator) = mulExp3( Exp({ mantissa: repayAmount }), Exp({ mantissa: vars.liquidationIncentiveMantissa }), Exp({ mantissa: vars.underlyingPriceUpscaled }) ); require(vars.mathErr == MathError.NO_ERROR, "ERR_GET_CLUTCHABLE_COLLATERAL_MATH_ERROR"); /* Calculate the mantissa form of the clutched collateral amount. */ (vars.mathErr, vars.clutchableCollateralAmountUpscaled) = divExp( vars.numerator, Exp({ mantissa: vars.collateralPriceUpscaled }) ); require(vars.mathErr == MathError.NO_ERROR, "ERR_GET_CLUTCHABLE_COLLATERAL_MATH_ERROR"); /* If the precision scalar is not 1, calculate the final form of the clutched collateral amount. */ vars.collateralPrecisionScalar = fyToken.collateralPrecisionScalar(); if (vars.collateralPrecisionScalar != 1) { (vars.mathErr, vars.clutchableCollateralAmount) = divUInt( vars.clutchableCollateralAmountUpscaled.mantissa, vars.collateralPrecisionScalar ); require(vars.mathErr == MathError.NO_ERROR, "ERR_GET_CLUTCHABLE_COLLATERAL_MATH_ERROR"); } else { vars.clutchableCollateralAmount = vars.clutchableCollateralAmountUpscaled.mantissa; } return vars.clutchableCollateralAmount; } /** * @notice Determines the current collateralization ratio for the given borrower account. * @param fyToken The fyToken to make the query against. * @param borrower The borrower account to make the query against. * @return A quotient if locked collateral is non-zero, otherwise zero. */ function getCurrentCollateralizationRatio(FyTokenInterface fyToken, address borrower) public view override returns (uint256) { Vault memory vault = vaults[address(fyToken)][borrower]; return getHypotheticalCollateralizationRatio(fyToken, borrower, vault.lockedCollateral, vault.debt); } struct GetHypotheticalAccountLiquidityLocalVars { MathError mathErr; uint256 collateralPriceUpscaled; uint256 collateralPrecisionScalar; uint256 collateralizationRatioMantissa; Exp debtValueUsd; Exp hypotheticalCollateralizationRatio; Exp lockedCollateralValueUsd; uint256 lockedCollateralUpscaled; uint256 oraclePricePrecisionScalar; uint256 underlyingPriceUpscaled; uint256 underlyingPrecisionScalar; } /** * @notice Determines the hypothetical collateralization ratio for the given locked * collateral and debt, at the current prices provided by the oracle. * * @dev The formula applied: collateralizationRatio = lockedCollateralValueUsd / debtValueUsd * * Requirements: * * - The vault must be open. * - `debt` must be non-zero. * - The oracle prices must be non-zero. * * @param fyToken The fyToken for which to make the query against. * @param borrower The borrower account for which to make the query against. * @param lockedCollateral The hypothetical locked collateral. * @param debt The hypothetical debt. * @return The hypothetical collateralization ratio as a percentage mantissa if locked * collateral is non-zero, otherwise zero. */ function getHypotheticalCollateralizationRatio( FyTokenInterface fyToken, address borrower, uint256 lockedCollateral, uint256 debt ) public view override returns (uint256) { GetHypotheticalAccountLiquidityLocalVars memory vars; /* If the vault is not open, a hypothetical collateralization ratio cannot be calculated. */ require(vaults[address(fyToken)][borrower].isOpen, "ERR_VAULT_NOT_OPEN"); /* Avoid the zero edge cases. */ if (lockedCollateral == 0) { return 0; } require(debt > 0, "ERR_GET_HYPOTHETICAL_COLLATERALIZATION_RATIO_DEBT_ZERO"); /* Grab the upscaled USD price of the collateral. */ ChainlinkOperatorInterface oracle = fintroller.oracle(); vars.collateralPriceUpscaled = oracle.getAdjustedPrice(fyToken.collateral().symbol()); /* Grab the upscaled USD price of the underlying. */ vars.underlyingPriceUpscaled = oracle.getAdjustedPrice(fyToken.underlying().symbol()); /* Upscale the collateral, which can have any precision, to mantissa precision. */ vars.collateralPrecisionScalar = fyToken.collateralPrecisionScalar(); if (vars.collateralPrecisionScalar != 1) { (vars.mathErr, vars.lockedCollateralUpscaled) = mulUInt(lockedCollateral, vars.collateralPrecisionScalar); require(vars.mathErr == MathError.NO_ERROR, "ERR_GET_HYPOTHETICAL_COLLATERALIZATION_RATIO_MATH_ERROR"); } else { vars.lockedCollateralUpscaled = lockedCollateral; } /* Calculate the USD value of the collateral. */ (vars.mathErr, vars.lockedCollateralValueUsd) = mulExp( Exp({ mantissa: vars.lockedCollateralUpscaled }), Exp({ mantissa: vars.collateralPriceUpscaled }) ); require(vars.mathErr == MathError.NO_ERROR, "ERR_GET_HYPOTHETICAL_COLLATERALIZATION_RATIO_MATH_ERROR"); /* Calculate the USD value of the debt. */ (vars.mathErr, vars.debtValueUsd) = mulExp( Exp({ mantissa: debt }), Exp({ mantissa: vars.underlyingPriceUpscaled }) ); require(vars.mathErr == MathError.NO_ERROR, "ERR_GET_HYPOTHETICAL_COLLATERALIZATION_RATIO_MATH_ERROR"); /** * Calculate the collateralization ratio by dividing the USD value of the hypothetical locked collateral by * the USD value of the debt. */ (vars.mathErr, vars.hypotheticalCollateralizationRatio) = divExp( vars.lockedCollateralValueUsd, vars.debtValueUsd ); require(vars.mathErr == MathError.NO_ERROR, "ERR_GET_HYPOTHETICAL_COLLATERALIZATION_RATIO_MATH_ERROR"); return vars.hypotheticalCollateralizationRatio.mantissa; } /** * @notice Reads the storage properties of a vault. * @return (uint256 debt, uint256 freeCollateral, uint256 lockedCollateral, bool isOpen). */ function getVault(FyTokenInterface fyToken, address borrower) external view override returns ( uint256, uint256, uint256, bool ) { return ( vaults[address(fyToken)][borrower].debt, vaults[address(fyToken)][borrower].freeCollateral, vaults[address(fyToken)][borrower].lockedCollateral, vaults[address(fyToken)][borrower].isOpen ); } /** * @notice Reads the debt held by the given account. * @return The debt held by the borrower, as an uint256. */ function getVaultDebt(FyTokenInterface fyToken, address borrower) external view override returns (uint256) { return vaults[address(fyToken)][borrower].debt; } /** * @notice Reads the amount of collateral that the given borrower account locked in the vault. * @return The collateral locked in the vault by the borrower, as an uint256. */ function getVaultLockedCollateral(FyTokenInterface fyToken, address borrower) external view override returns (uint256) { return vaults[address(fyToken)][borrower].lockedCollateral; } /** * @notice Checks whether the borrower account can be liquidated or not. * @param fyToken The fyToken for which to make the query against. * @param borrower The borrower account for which to make the query against. * @return bool true = is underwater, otherwise not. */ function isAccountUnderwater(FyTokenInterface fyToken, address borrower) external view override returns (bool) { Vault memory vault = vaults[address(fyToken)][borrower]; if (!vault.isOpen || vault.debt == 0) { return false; } uint256 currentCollateralizationRatioMantissa = getCurrentCollateralizationRatio(fyToken, borrower); uint256 thresholdCollateralizationRatioMantissa = fintroller.getBondCollateralizationRatio(fyToken); return currentCollateralizationRatioMantissa < thresholdCollateralizationRatioMantissa; } /** * @notice Checks whether the borrower account has a vault opened for a particular fyToken. */ function isVaultOpen(FyTokenInterface fyToken, address borrower) external view override returns (bool) { return vaults[address(fyToken)][borrower].isOpen; } /** * NON-CONSTANT FUNCTIONS */ /** * @notice Transfers the collateral from the borrower's vault to the liquidator account. * * @dev Emits a {ClutchCollateral} event. * * Requirements: * * - Can only be called by the fyToken. * - There must be enough collateral in the borrower's vault. * * @param fyToken The address of the fyToken contract. * @param liquidator The account who repays the borrower's debt and receives the collateral. * @param borrower The account who fell underwater and is liquidated. * @param collateralAmount The amount of collateral to clutch, specified in the collateral's decimal system. * @return bool true = success, otherwise it reverts. */ function clutchCollateral( FyTokenInterface fyToken, address liquidator, address borrower, uint256 collateralAmount ) external override nonReentrant returns (bool) { /* Checks: the caller is the fyToken. */ require(msg.sender == address(fyToken), "ERR_CLUTCH_COLLATERAL_NOT_AUTHORIZED"); /* Checks: there is enough clutchable collateral in the vault. */ uint256 lockedCollateral = vaults[address(fyToken)][borrower].lockedCollateral; require(lockedCollateral >= collateralAmount, "ERR_INSUFFICIENT_LOCKED_COLLATERAL"); /* Calculate the new locked collateral amount. */ MathError mathErr; uint256 newLockedCollateral; (mathErr, newLockedCollateral) = subUInt(lockedCollateral, collateralAmount); assert(mathErr == MathError.NO_ERROR); /* Effects: update the vault. */ vaults[address(fyToken)][borrower].lockedCollateral = newLockedCollateral; /* Interactions: transfer the collateral. */ fyToken.collateral().safeTransfer(liquidator, collateralAmount); emit ClutchCollateral(fyToken, liquidator, borrower, collateralAmount); return true; } /** * @notice Deposits collateral into the account's vault. * * @dev Emits a {DepositCollateral} event. * * Requirements: * * - The vault must be open. * - The amount to deposit cannot be zero. * - The Fintroller must allow this action to be performed. * - The caller must have allowed this contract to spend `collateralAmount` tokens. * * @param fyToken The address of the fyToken contract. * @param collateralAmount The amount of collateral to deposit. * @return bool true = success, otherwise it reverts. */ function depositCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external override isVaultOpenForMsgSender(fyToken) nonReentrant returns (bool) { /* Checks: the zero edge case. */ require(collateralAmount > 0, "ERR_DEPOSIT_COLLATERAL_ZERO"); /* Checks: the Fintroller allows this action to be performed. */ require(fintroller.getDepositCollateralAllowed(fyToken), "ERR_DEPOSIT_COLLATERAL_NOT_ALLOWED"); /* Effects: update storage. */ MathError mathErr; uint256 hypotheticalFreeCollateral; (mathErr, hypotheticalFreeCollateral) = addUInt( vaults[address(fyToken)][msg.sender].freeCollateral, collateralAmount ); require(mathErr == MathError.NO_ERROR, "ERR_DEPOSIT_COLLATERAL_MATH_ERROR"); vaults[address(fyToken)][msg.sender].freeCollateral = hypotheticalFreeCollateral; /* Interactions: perform the Erc20 transfer. */ fyToken.collateral().safeTransferFrom(msg.sender, address(this), collateralAmount); emit DepositCollateral(fyToken, msg.sender, collateralAmount); return true; } struct FreeCollateralLocalVars { MathError mathErr; uint256 collateralizationRatioMantissa; uint256 hypotheticalCollateralizationRatioMantissa; uint256 newFreeCollateral; uint256 newLockedCollateral; } /** * @notice Frees a portion or all of the locked collateral. * @dev Emits a {FreeCollateral} event. * * Requirements: * * - The vault must be open. * - The amount to free cannot be zero. * - There must be enough locked collateral. * - The borrower account cannot fall below the collateralization ratio. * * @param fyToken The address of the fyToken contract. * @param collateralAmount The amount of locked collateral to free. * @return bool true = success, otherwise it reverts. */ function freeCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external override isVaultOpenForMsgSender(fyToken) returns (bool) { FreeCollateralLocalVars memory vars; /* Checks: the zero edge case. */ require(collateralAmount > 0, "ERR_FREE_COLLATERAL_ZERO"); /* Checks: enough locked collateral. */ Vault memory vault = vaults[address(fyToken)][msg.sender]; require(vault.lockedCollateral >= collateralAmount, "ERR_INSUFFICIENT_LOCKED_COLLATERAL"); /* This operation can't fail because of the first `require` in this function. */ (vars.mathErr, vars.newLockedCollateral) = subUInt(vault.lockedCollateral, collateralAmount); assert(vars.mathErr == MathError.NO_ERROR); /* Checks: the hypothetical collateralization ratio is above the threshold. */ if (vault.debt > 0) { vars.hypotheticalCollateralizationRatioMantissa = getHypotheticalCollateralizationRatio( fyToken, msg.sender, vars.newLockedCollateral, vault.debt ); vars.collateralizationRatioMantissa = fintroller.getBondCollateralizationRatio(fyToken); require( vars.hypotheticalCollateralizationRatioMantissa >= vars.collateralizationRatioMantissa, "ERR_BELOW_COLLATERALIZATION_RATIO" ); } /* Effects: update storage. */ vaults[address(fyToken)][msg.sender].lockedCollateral = vars.newLockedCollateral; (vars.mathErr, vars.newFreeCollateral) = addUInt(vault.freeCollateral, collateralAmount); require(vars.mathErr == MathError.NO_ERROR, "ERR_FREE_COLLATERAL_MATH_ERROR"); vaults[address(fyToken)][msg.sender].freeCollateral = vars.newFreeCollateral; emit FreeCollateral(fyToken, msg.sender, collateralAmount); return true; } /** * @notice Locks a portion or all of the free collateral to make it eligible for borrowing. * @dev Emits a {LockCollateral} event. * * Requirements: * * - The vault must be open. * - The amount to lock cannot be zero. * - There must be enough free collateral. * * @param fyToken The address of the fyToken contract. * @param collateralAmount The amount of free collateral to lock. * @return bool true = success, otherwise it reverts. */ function lockCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external override isVaultOpenForMsgSender(fyToken) returns (bool) { /* Avoid the zero edge case. */ require(collateralAmount > 0, "ERR_LOCK_COLLATERAL_ZERO"); Vault memory vault = vaults[address(fyToken)][msg.sender]; require(vault.freeCollateral >= collateralAmount, "ERR_INSUFFICIENT_FREE_COLLATERAL"); MathError mathErr; uint256 newLockedCollateral; (mathErr, newLockedCollateral) = addUInt(vault.lockedCollateral, collateralAmount); require(mathErr == MathError.NO_ERROR, "ERR_LOCK_COLLATERAL_MATH_ERROR"); vaults[address(fyToken)][msg.sender].lockedCollateral = newLockedCollateral; /* This operation can't fail because of the first `require` in this function. */ uint256 hypotheticalFreeCollateral; (mathErr, hypotheticalFreeCollateral) = subUInt(vault.freeCollateral, collateralAmount); assert(mathErr == MathError.NO_ERROR); vaults[address(fyToken)][msg.sender].freeCollateral = hypotheticalFreeCollateral; emit LockCollateral(fyToken, msg.sender, collateralAmount); return true; } /** * @notice Opens a Vault for the caller. * @dev Emits an {OpenVault} event. * * Requirements: * * - The vault cannot be already open. * - The fyToken must pass the inspection. * * @param fyToken The address of the fyToken contract for which to open the vault. * @return bool true = success, otherwise it reverts. */ function openVault(FyTokenInterface fyToken) external override returns (bool) { require(fyToken.isFyToken(), "ERR_OPEN_VAULT_FYTOKEN_INSPECTION"); require(vaults[address(fyToken)][msg.sender].isOpen == false, "ERR_VAULT_OPEN"); vaults[address(fyToken)][msg.sender].isOpen = true; emit OpenVault(fyToken, msg.sender); return true; } /** * @notice Updates the debt accrued by a particular borrower account. * * @dev Emits a {SetVaultDebt} event. * * Requirements: * * - Can only be called by the fyToken. * * @param fyToken The address of the fyToken contract. * @param borrower The borrower account for which to update the debt. * @param newVaultDebt The new debt to assign to the borrower account. * @return bool=true success, otherwise it reverts. */ function setVaultDebt( FyTokenInterface fyToken, address borrower, uint256 newVaultDebt ) external override returns (bool) { /* Checks: the caller is the fyToken. */ require(msg.sender == address(fyToken), "ERR_SET_VAULT_DEBT_NOT_AUTHORIZED"); /* Effects: update storage. */ uint256 oldVaultDebt = vaults[address(fyToken)][borrower].debt; vaults[address(fyToken)][borrower].debt = newVaultDebt; emit SetVaultDebt(fyToken, borrower, oldVaultDebt, newVaultDebt); return true; } /** * @notice Withdraws a portion or all of the free collateral. * * @dev Emits a {WithdrawCollateral} event. * * Requirements: * * - The vault must be open. * - The amount to withdraw cannot be zero. * - There must be enough free collateral in the vault. * * @param fyToken The address of the fyToken contract. * @param collateralAmount The amount of collateral to withdraw. * @return bool true = success, otherwise it reverts. */ function withdrawCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external override isVaultOpenForMsgSender(fyToken) nonReentrant returns (bool) { /* Checks: the zero edge case. */ require(collateralAmount > 0, "ERR_WITHDRAW_COLLATERAL_ZERO"); /* Checks: there is enough free collateral. */ require( vaults[address(fyToken)][msg.sender].freeCollateral >= collateralAmount, "ERR_INSUFFICIENT_FREE_COLLATERAL" ); /* Effects: update storage. */ MathError mathErr; uint256 newFreeCollateral; (mathErr, newFreeCollateral) = subUInt(vaults[address(fyToken)][msg.sender].freeCollateral, collateralAmount); /* This operation can't fail because of the first `require` in this function. */ assert(mathErr == MathError.NO_ERROR); vaults[address(fyToken)][msg.sender].freeCollateral = newFreeCollateral; /* Interactions: perform the Erc20 transfer. */ fyToken.collateral().safeTransfer(msg.sender, collateralAmount); emit WithdrawCollateral(fyToken, msg.sender, collateralAmount); return true; } }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; /** * @title Address * @author Paul Razvan Berg * @notice Collection of functions related to the address type. * @dev Forked from OpenZeppelin * https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v3.1.0/contracts/utils/Address.sol */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // 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); } }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; import "./AdminInterface.sol"; /** * @title Admin * @author Paul Razvan Berg * @notice Contract module which provides a basic access control mechanism, where there is * an account (an admin) that can be granted exclusive access to specific functions. * * By default, the admin account will be the one that deploys the contract. This can later * be changed with {transferAdmin}. * * This module is used through inheritance. It will make available the modifier `onlyAdmin`, * which can be applied to your functions to restrict their use to the admin. * * @dev Forked from OpenZeppelin * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.1.0/contracts/access/Ownable.sol */ abstract contract Admin is AdminInterface { /** * @notice Throws if called by any account other than the admin. */ modifier onlyAdmin() { require(admin == msg.sender, "ERR_NOT_ADMIN"); _; } /** * @notice Initializes the contract setting the deployer as the initial admin. */ constructor() { address msgSender = msg.sender; admin = msgSender; emit TransferAdmin(address(0x00), msgSender); } /** * @notice Leaves the contract without admin, so it will not be possible to call * `onlyAdmin` functions anymore. * * Requirements: * * - The caller must be the administrator. * * WARNING: Doing this will leave the contract without an admin, * thereby removing any functionality that is only available to the admin. */ function _renounceAdmin() external virtual override onlyAdmin { emit TransferAdmin(admin, address(0x00)); admin = address(0x00); } /** * @notice Transfers the admin of the contract to a new account (`newAdmin`). * Can only be called by the current admin. * @param newAdmin The acount of the new admin. */ function _transferAdmin(address newAdmin) external virtual override onlyAdmin { require(newAdmin != address(0x00), "ERR_SET_ADMIN_ZERO_ADDRESS"); emit TransferAdmin(admin, newAdmin); admin = newAdmin; } }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; import "./AdminStorage.sol"; /** * @title AdminInterface * @author Paul Razvan Berg */ abstract contract AdminInterface is AdminStorage { /** * NON-CONSTANT FUNCTIONS */ function _renounceAdmin() external virtual; function _transferAdmin(address newAdmin) external virtual; /** * EVENTS */ event TransferAdmin(address indexed oldAdmin, address indexed newAdmin); }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; abstract contract AdminStorage { /** * @notice The address of the administrator account or contract. */ address public admin; }
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; /** * @title AggregatorV3Interface * @author Hifi * @dev Forked from Chainlink * https://github.com/smartcontractkit/chainlink/blob/v0.9.9/evm-contracts/src/v0.7/interfaces/AggregatorV3Interface.sol */ interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); /* * getRoundData and latestRoundData should both raise "No data present" * if they do not have data to report, instead of returning unset values * which could be misinterpreted as actual reported values. */ function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; import "./BalanceSheetStorage.sol"; /** * @title BalanceSheetInterface * @author Hifi */ abstract contract BalanceSheetInterface is BalanceSheetStorage { /** * CONSTANT FUNCTIONS */ function getClutchableCollateral(FyTokenInterface fyToken, uint256 repayAmount) external view virtual returns (uint256); function getCurrentCollateralizationRatio(FyTokenInterface fyToken, address borrower) public view virtual returns (uint256); function getHypotheticalCollateralizationRatio( FyTokenInterface fyToken, address borrower, uint256 lockedCollateral, uint256 debt ) public view virtual returns (uint256); function getVault(FyTokenInterface fyToken, address borrower) external view virtual returns ( uint256, uint256, uint256, bool ); function getVaultDebt(FyTokenInterface fyToken, address borrower) external view virtual returns (uint256); function getVaultLockedCollateral(FyTokenInterface fyToken, address borrower) external view virtual returns (uint256); function isAccountUnderwater(FyTokenInterface fyToken, address borrower) external view virtual returns (bool); function isVaultOpen(FyTokenInterface fyToken, address borrower) external view virtual returns (bool); /** * NON-CONSTANT FUNCTIONS */ function clutchCollateral( FyTokenInterface fyToken, address liquidator, address borrower, uint256 clutchedCollateralAmount ) external virtual returns (bool); function depositCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external virtual returns (bool); function freeCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external virtual returns (bool); function lockCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external virtual returns (bool); function openVault(FyTokenInterface fyToken) external virtual returns (bool); function setVaultDebt( FyTokenInterface fyToken, address borrower, uint256 newVaultDebt ) external virtual returns (bool); function withdrawCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external virtual returns (bool); /** * EVENTS */ event ClutchCollateral( FyTokenInterface indexed fyToken, address indexed liquidator, address indexed borrower, uint256 clutchedCollateralAmount ); event DepositCollateral(FyTokenInterface indexed fyToken, address indexed borrower, uint256 collateralAmount); event FreeCollateral(FyTokenInterface indexed fyToken, address indexed borrower, uint256 collateralAmount); event LockCollateral(FyTokenInterface indexed fyToken, address indexed borrower, uint256 collateralAmount); event OpenVault(FyTokenInterface indexed fyToken, address indexed borrower); event SetVaultDebt(FyTokenInterface indexed fyToken, address indexed borrower, uint256 oldDebt, uint256 newDebt); event WithdrawCollateral(FyTokenInterface indexed fyToken, address indexed borrower, uint256 collateralAmount); }
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; import "./FyTokenInterface.sol"; /** * @title BalanceSheetStorage * @author Hifi */ abstract contract BalanceSheetStorage { struct Vault { uint256 debt; uint256 freeCollateral; uint256 lockedCollateral; bool isOpen; } /** * @notice The unique Fintroller associated with this contract. */ FintrollerInterface public fintroller; /** * @dev One vault for each fyToken for each account. */ mapping(address => mapping(address => Vault)) internal vaults; /** * @notice Indicator that this is a BalanceSheet contract, for inspection. */ bool public constant isBalanceSheet = true; }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; /** * @notice Possible error codes that can be returned. */ enum MathError { NO_ERROR, DIVISION_BY_ZERO, INTEGER_OVERFLOW, INTEGER_UNDERFLOW, MODULO_BY_ZERO } /** * @title CarefulMath * @author Paul Razvan Berg * @notice Exponential module for storing fixed-precision decimals. * @dev Forked from Compound * https://github.com/compound-finance/compound-protocol/blob/v2.8.1/contracts/CarefulMath.sol */ abstract contract CarefulMath { /** * @notice Adds two numbers, returns an error on overflow. */ function addUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) { uint256 c = a + b; if (c >= a) { return (MathError.NO_ERROR, c); } else { return (MathError.INTEGER_OVERFLOW, 0); } } /** * @notice Add `a` and `b` and then subtract `c`. */ function addThenSubUInt( uint256 a, uint256 b, uint256 c ) internal pure returns (MathError, uint256) { (MathError err0, uint256 sum) = addUInt(a, b); if (err0 != MathError.NO_ERROR) { return (err0, 0); } return subUInt(sum, c); } /** * @notice Integer division of two numbers, truncating the quotient. */ function divUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) { if (b == 0) { return (MathError.DIVISION_BY_ZERO, 0); } return (MathError.NO_ERROR, a / b); } /** * @notice Returns the remainder of dividing two numbers. * @dev Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). */ function modUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) { if (b == 0) { return (MathError.MODULO_BY_ZERO, 0); } return (MathError.NO_ERROR, a % b); } /** * @notice Multiplies two numbers, returns an error on overflow. */ function mulUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) { if (a == 0) { return (MathError.NO_ERROR, 0); } uint256 c = a * b; if (c / a != b) { return (MathError.INTEGER_OVERFLOW, 0); } else { return (MathError.NO_ERROR, c); } } /** * @notice Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend). */ function subUInt(uint256 a, uint256 b) internal pure returns (MathError, uint256) { if (b <= a) { return (MathError.NO_ERROR, a - b); } else { return (MathError.INTEGER_UNDERFLOW, 0); } } }
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; import "./CarefulMath.sol"; import "./Erc20Interface.sol"; import "./ChainlinkOperatorStorage.sol"; import "./AggregatorV3Interface.sol"; /** * @title ChainlinkOperatorInterface * @author Hifi */ abstract contract ChainlinkOperatorInterface is ChainlinkOperatorStorage { /** * EVENTS */ event DeleteFeed(Erc20Interface indexed asset, AggregatorV3Interface indexed feed); event SetFeed(Erc20Interface indexed asset, AggregatorV3Interface indexed feed); /** * CONSTANT FUNCTIONS. */ function getAdjustedPrice(string memory symbol) external view virtual returns (uint256); function getFeed(string memory symbol) external view virtual returns ( Erc20Interface, AggregatorV3Interface, bool ); function getPrice(string memory symbol) public view virtual returns (uint256); /** * NON-CONSTANT FUNCTIONS. */ function deleteFeed(string memory symbol) external virtual returns (bool); function setFeed(Erc20Interface asset, AggregatorV3Interface feed) external virtual returns (bool); }
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; import "./Erc20Interface.sol"; import "./AggregatorV3Interface.sol"; /** * @title ChainlinkOperatorStorage * @author Hifi */ abstract contract ChainlinkOperatorStorage { struct Feed { Erc20Interface asset; AggregatorV3Interface id; bool isSet; } /** * @dev Mapping between Erc20 symbols and Feed structs. */ mapping(string => Feed) internal feeds; /** * @notice Chainlink price precision for USD-quoted data. */ uint256 public constant pricePrecision = 8; /** * @notice The ratio between mantissa precision (1e18) and the Chainlink price precision (1e8). */ uint256 public constant pricePrecisionScalar = 1.0e10; }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; import "./Erc20Storage.sol"; /** * @title Erc20Interface * @author Paul Razvan Berg * @notice Interface of the Erc20 standard * @dev Forked from OpenZeppelin * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.2.0/contracts/token/ERC20/IERC20.sol */ abstract contract Erc20Interface is Erc20Storage { /** * CONSTANT FUNCTIONS */ function allowance(address owner, address spender) external view virtual returns (uint256); function balanceOf(address account) external view virtual returns (uint256); /** * NON-CONSTANT FUNCTIONS */ function approve(address spender, uint256 amount) external virtual returns (bool); function transfer(address recipient, uint256 amount) external virtual returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external virtual returns (bool); /** * EVENTS */ event Approval(address indexed owner, address indexed spender, uint256 amount); event Burn(address indexed holder, uint256 burnAmount); event Mint(address indexed beneficiary, uint256 mintAmount); event Transfer(address indexed from, address indexed to, uint256 amount); }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; /** * @title ExponentialStorage * @author Paul Razvan Berg * @notice The storage interface ancillary to an Erc20 contract. */ abstract contract Erc20Storage { /** * @notice Returns the number of decimals used to get its user representation. */ uint8 public decimals; /** * @notice Returns the name of the token. */ string public name; /** * @notice Returns the symbol of the token, usually a shorter version of * the name. */ string public symbol; /** * @notice Returns the amount of tokens in existence. */ uint256 public totalSupply; mapping(address => mapping(address => uint256)) internal allowances; mapping(address => uint256) internal balances; }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; import "./CarefulMath.sol"; import "./ExponentialStorage.sol"; /** * @title Exponential module for storing fixed-precision decimals. * @author Paul Razvan Berg * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places. * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is: `Exp({mantissa: 5100000000000000000})`. * @dev Forked from Compound * https://github.com/compound-finance/compound-protocol/blob/v2.6/contracts/Exponential.sol */ abstract contract Exponential is CarefulMath, /* no dependency */ ExponentialStorage /* no dependency */ { /** * @dev Adds two exponentials, returning a new exponential. */ function addExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) { (MathError error, uint256 result) = addUInt(a.mantissa, b.mantissa); return (error, Exp({ mantissa: result })); } /** * @dev Divides two exponentials, returning a new exponential. * (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b. * NOTE: Returns an error if (`num` * 10e18) > MAX_INT, or if `denom` is zero. */ function divExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) { (MathError err0, uint256 scaledNumerator) = mulUInt(a.mantissa, expScale); if (err0 != MathError.NO_ERROR) { return (err0, Exp({ mantissa: 0 })); } (MathError err1, uint256 rational) = divUInt(scaledNumerator, b.mantissa); if (err1 != MathError.NO_ERROR) { return (err1, Exp({ mantissa: 0 })); } return (MathError.NO_ERROR, Exp({ mantissa: rational })); } /** * @dev Multiplies two exponentials, returning a new exponential. */ function mulExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) { (MathError err0, uint256 doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa); if (err0 != MathError.NO_ERROR) { return (err0, Exp({ mantissa: 0 })); } /* * We add half the scale before dividing so that we get rounding instead of truncation. * See "Listing 6" and text above it at https://accu.org/index.php/journals/1717 * Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18. */ (MathError err1, uint256 doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct); if (err1 != MathError.NO_ERROR) { return (err1, Exp({ mantissa: 0 })); } (MathError err2, uint256 product) = divUInt(doubleScaledProductWithHalfScale, expScale); /* The only possible error `div` is MathError.DIVISION_BY_ZERO but we control `expScale` and it's not zero. */ assert(err2 == MathError.NO_ERROR); return (MathError.NO_ERROR, Exp({ mantissa: product })); } /** * @dev Multiplies three exponentials, returning a new exponential. */ function mulExp3( Exp memory a, Exp memory b, Exp memory c ) internal pure returns (MathError, Exp memory) { (MathError err, Exp memory ab) = mulExp(a, b); if (err != MathError.NO_ERROR) { return (err, ab); } return mulExp(ab, c); } /** * @dev Subtracts two exponentials, returning a new exponential. */ function subExp(Exp memory a, Exp memory b) internal pure returns (MathError, Exp memory) { (MathError error, uint256 result) = subUInt(a.mantissa, b.mantissa); return (error, Exp({ mantissa: result })); } }
/* SPDX-License-Identifier: LPGL-3.0-or-later */ pragma solidity ^0.7.0; /** * @title ExponentialStorage * @author Paul Razvan Berg * @notice The storage interface ancillary to an Exponential contract. */ abstract contract ExponentialStorage { struct Exp { uint256 mantissa; } /** * @dev In Exponential denomination, 1e18 is 1. */ uint256 internal constant expScale = 1e18; uint256 internal constant halfExpScale = expScale / 2; uint256 internal constant mantissaOne = expScale; }
/* SPDX-License-Identifier: LPGL-3.0-or-later */ pragma solidity ^0.7.0; import "./FintrollerStorage.sol"; import "./FyTokenInterface.sol"; import "./ChainlinkOperatorInterface.sol"; abstract contract FintrollerInterface is FintrollerStorage { /** * CONSTANT FUNCTIONS */ function getBond(FyTokenInterface fyToken) external view virtual returns ( uint256 debtCeiling, uint256 collateralizationRatioMantissa, bool isBorrowAllowed, bool isDepositCollateralAllowed, bool isLiquidateBorrowAllowed, bool isListed, bool isRedeemFyTokenAllowed, bool isRepayBorrowAllowed, bool isSupplyUnderlyingAllowed ); function getBorrowAllowed(FyTokenInterface fyToken) external view virtual returns (bool); function getBondCollateralizationRatio(FyTokenInterface fyToken) external view virtual returns (uint256); function getBondDebtCeiling(FyTokenInterface fyToken) external view virtual returns (uint256); function getDepositCollateralAllowed(FyTokenInterface fyToken) external view virtual returns (bool); function getLiquidateBorrowAllowed(FyTokenInterface fyToken) external view virtual returns (bool); function getRedeemFyTokensAllowed(FyTokenInterface fyToken) external view virtual returns (bool); function getRepayBorrowAllowed(FyTokenInterface fyToken) external view virtual returns (bool); function getSupplyUnderlyingAllowed(FyTokenInterface fyToken) external view virtual returns (bool); /** * NON-CONSTANT FUNCTIONS */ function listBond(FyTokenInterface fyToken) external virtual returns (bool); function setBondCollateralizationRatio(FyTokenInterface fyToken, uint256 newCollateralizationRatioMantissa) external virtual returns (bool); function setBondDebtCeiling(FyTokenInterface fyToken, uint256 newDebtCeiling) external virtual returns (bool); function setBorrowAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool); function setDepositCollateralAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool); function setLiquidateBorrowAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool); function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external virtual returns (bool); function setOracle(ChainlinkOperatorInterface newOracle) external virtual returns (bool); function setRedeemFyTokensAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool); function setRepayBorrowAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool); function setSupplyUnderlyingAllowed(FyTokenInterface fyToken, bool state) external virtual returns (bool); /** * EVENTS */ event ListBond(address indexed admin, FyTokenInterface indexed fyToken); event SetBorrowAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state); event SetBondCollateralizationRatio( address indexed admin, FyTokenInterface indexed fyToken, uint256 oldCollateralizationRatio, uint256 newCollateralizationRatio ); event SetBondDebtCeiling( address indexed admin, FyTokenInterface indexed fyToken, uint256 oldDebtCeiling, uint256 newDebtCeiling ); event SetDepositCollateralAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state); event SetLiquidateBorrowAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state); event SetLiquidationIncentive( address indexed admin, uint256 oldLiquidationIncentive, uint256 newLiquidationIncentive ); event SetRedeemFyTokensAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state); event SetRepayBorrowAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state); event SetOracle(address indexed admin, address oldOracle, address newOracle); event SetSupplyUnderlyingAllowed(address indexed admin, FyTokenInterface indexed fyToken, bool state); }
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; import "./Exponential.sol"; import "./FyTokenInterface.sol"; import "./ChainlinkOperatorInterface.sol"; /** * @title FintrollerStorage * @author Hifi */ abstract contract FintrollerStorage is Exponential { struct Bond { Exp collateralizationRatio; uint256 debtCeiling; bool isBorrowAllowed; bool isDepositCollateralAllowed; bool isLiquidateBorrowAllowed; bool isListed; bool isRedeemFyTokenAllowed; bool isRepayBorrowAllowed; bool isSupplyUnderlyingAllowed; } /** * @dev Maps the fyToken address to the Bond structs. */ mapping(FyTokenInterface => Bond) internal bonds; /** * @notice The contract that provides price data for the collateral and the underlying asset. */ ChainlinkOperatorInterface public oracle; /** * @notice Multiplier representing the discount on collateral that a liquidator receives. */ uint256 public liquidationIncentiveMantissa; /** * @dev The threshold below which the collateralization ratio cannot be set, equivalent to 100%. */ uint256 internal constant collateralizationRatioLowerBoundMantissa = 1.0e18; /** * @dev The threshold above which the collateralization ratio cannot be set, equivalent to 10,000%. */ uint256 internal constant collateralizationRatioUpperBoundMantissa = 1.0e20; /** * @dev The dafault collateralization ratio set when a new bond is listed, equivalent to 150%. */ uint256 internal constant defaultCollateralizationRatioMantissa = 1.5e18; /** * @dev The threshold below which the liquidation incentive cannot be set, equivalent to 100%. */ uint256 internal constant liquidationIncentiveLowerBoundMantissa = 1.0e18; /** * @dev The threshold above which the liquidation incentive cannot be set, equivalent to 150%. */ uint256 internal constant liquidationIncentiveUpperBoundMantissa = 1.5e18; /** * @notice Indicator that this is a Fintroller contract, for inspection. */ bool public constant isFintroller = true; }
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; import "./Erc20Interface.sol"; import "./FyTokenStorage.sol"; /** * @title FyTokenInterface * @author Hifi */ abstract contract FyTokenInterface is FyTokenStorage, /* no dependency */ Erc20Interface /* one dependency */ { /** * CONSTANT FUNCTIONS */ function isMatured() public view virtual returns (bool); /** * NON-CONSTANT FUNCTIONS */ function borrow(uint256 borrowAmount) external virtual returns (bool); function burn(address holder, uint256 burnAmount) external virtual returns (bool); function liquidateBorrow(address borrower, uint256 repayAmount) external virtual returns (bool); function mint(address beneficiary, uint256 mintAmount) external virtual returns (bool); function repayBorrow(uint256 repayAmount) external virtual returns (bool); function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (bool); function _setFintroller(FintrollerInterface newFintroller) external virtual returns (bool); /** * EVENTS */ event Borrow(address indexed borrower, uint256 borrowAmount); event LiquidateBorrow( address indexed liquidator, address indexed borrower, uint256 repayAmount, uint256 clutchedCollateralAmount ); event RepayBorrow(address indexed payer, address indexed borrower, uint256 repayAmount, uint256 newDebt); event SetFintroller(address indexed admin, FintrollerInterface oldFintroller, FintrollerInterface newFintroller); }
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; import "./Erc20Interface.sol"; import "./BalanceSheetInterface.sol"; import "./FintrollerInterface.sol"; import "./RedemptionPoolInterface.sol"; /** * @title FyTokenStorage * @author Hifi */ abstract contract FyTokenStorage { /** * STORAGE PROPERTIES */ /** * @notice The global debt registry. */ BalanceSheetInterface public balanceSheet; /** * @notice The Erc20 asset that backs the borrows of this fyToken. */ Erc20Interface public collateral; /** * @notice The ratio between mantissa precision (1e18) and the collateral precision. */ uint256 public collateralPrecisionScalar; /** * @notice Unix timestamp in seconds for when this token expires. */ uint256 public expirationTime; /** * @notice The unique Fintroller associated with this contract. */ FintrollerInterface public fintroller; /** * @notice The unique Redemption Pool associated with this contract. */ RedemptionPoolInterface public redemptionPool; /** * @notice The Erc20 underlying, or target, asset for this fyToken. */ Erc20Interface public underlying; /** * @notice The ratio between mantissa precision (1e18) and the underlying precision. */ uint256 public underlyingPrecisionScalar; /** * @notice Indicator that this is a FyToken contract, for inspection. */ bool public constant isFyToken = true; }
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; import "./RedemptionPoolStorage.sol"; /** * @title RedemptionPoolInterface * @author Hifi */ abstract contract RedemptionPoolInterface is RedemptionPoolStorage { /** * NON-CONSTANT FUNCTIONS */ function redeemFyTokens(uint256 fyTokenAmount) external virtual returns (bool); function supplyUnderlying(uint256 underlyingAmount) external virtual returns (bool); /** * EVENTS */ event RedeemFyTokens(address indexed account, uint256 fyTokenAmount, uint256 underlyingAmount); event SupplyUnderlying(address indexed account, uint256 underlyingAmount, uint256 fyTokenAmount); }
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; import "./FintrollerInterface.sol"; import "./FyTokenInterface.sol"; /** * @title RedemptionPoolStorage * @author Hifi */ abstract contract RedemptionPoolStorage { /** * @notice The unique Fintroller associated with this contract. */ FintrollerInterface public fintroller; /** * @notice The amount of the underlying asset available to be redeemed after maturation. */ uint256 public totalUnderlyingSupply; /** * The unique fyToken associated with this Redemption Pool. */ FyTokenInterface public fyToken; /** * @notice Indicator that this is a Redemption Pool contract, for inspection. */ bool public constant isRedemptionPool = true; }
/* SPDX-License-Identifier: LGPL-3.0-or-later */ pragma solidity ^0.7.0; /** * @title ReentrancyGuard * @author Paul Razvan Berg * @notice Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * @dev Forked from OpenZeppelin * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.1.0/contracts/math/ReentrancyGuard.sol */ abstract contract ReentrancyGuard { bool private notEntered; /* * Storing an initial non-zero value makes deployment a bit more expensive * but in exchange the refund on every call to nonReentrant will be lower * in amount. Since refunds are capped to a percetange of the total * transaction's gas, it is best to keep them low in cases like this * one, to increase the likelihood of the full refund coming into effect. */ constructor() { notEntered = true; } /** * @notice Prevents a contract from calling itself, directly or indirectly. * @dev Calling a `nonReentrant` function from another `nonReentrant` function * is not supported. It is possible to prevent this from happening by making * the `nonReentrant` function external, and make it call a `private` * function that does the actual work. */ modifier nonReentrant() { /* On the first call to nonReentrant, _notEntered will be true. */ require(notEntered, "ERR_REENTRANT_CALL"); /* Any calls to nonReentrant after this point will fail. */ notEntered = false; _; /* * By storing the original value once again, a refund is triggered (see * https://eips.ethereum.org/EIPS/eip-2200). */ notEntered = true; } }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; import "./Erc20Interface.sol"; import "./Address.sol"; /** * @title SafeErc20.sol * @author Paul Razvan Berg * @notice Wraps around Erc20 operations that throw on failure (when the token contract * returns false). Tokens that return no value (and instead revert or throw * on failure) are also supported, non-reverting calls are assumed to be successful. * * To use this library you can add a `using SafeErc20 for Erc20Interface;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. * * @dev Forked from OpenZeppelin * https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v3.1.0/contracts/utils/Address.sol */ library SafeErc20 { using Address for address; /** * INTERNAL FUNCTIONS */ function safeTransfer( Erc20Interface token, address to, uint256 amount ) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, amount)); } function safeTransferFrom( Erc20Interface token, address from, address to, uint256 amount ) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, amount)); } /** * PRIVATE FUNCTIONS */ /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it cannot be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function callOptionalReturn(Erc20Interface token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = functionCall(address(token), data, "ERR_SAFE_ERC20_LOW_LEVEL_CALL"); if (returndata.length > 0) { /* Return data is optional. */ require(abi.decode(returndata, (bool)), "ERR_SAFE_ERC20_ERC20_OPERATION"); } } function functionCall( address target, bytes memory data, string memory errorMessage ) private returns (bytes memory) { require(target.isContract(), "ERR_SAFE_ERC20_CALL_TO_NON_CONTRACT"); /* solhint-disable-next-line avoid-low-level-calls */ (bool success, bytes memory returndata) = target.call(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); } } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract FintrollerInterface","name":"fintroller_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"indexed":true,"internalType":"address","name":"liquidator","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"clutchedCollateralAmount","type":"uint256"}],"name":"ClutchCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"DepositCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"FreeCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"LockCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"}],"name":"OpenVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldDebt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDebt","type":"uint256"}],"name":"SetVaultDebt","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"TransferAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"WithdrawCollateral","type":"event"},{"inputs":[],"name":"_renounceAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"_transferAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"clutchCollateral","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"depositCollateral","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fintroller","outputs":[{"internalType":"contract FintrollerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"freeCollateral","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"uint256","name":"repayAmount","type":"uint256"}],"name":"getClutchableCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"}],"name":"getCurrentCollateralizationRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"lockedCollateral","type":"uint256"},{"internalType":"uint256","name":"debt","type":"uint256"}],"name":"getHypotheticalCollateralizationRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"}],"name":"getVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"}],"name":"getVaultDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"}],"name":"getVaultLockedCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"}],"name":"isAccountUnderwater","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isBalanceSheet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"}],"name":"isVaultOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"lockCollateral","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"}],"name":"openVault","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"newVaultDebt","type":"uint256"}],"name":"setVaultDebt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract FyTokenInterface","name":"fyToken","type":"address"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"withdrawCollateral","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620034f4380380620034f4833981810160405260208110156200003757600080fd5b50516000805460ff19166001178155600280546001600160a01b03191633908117909155604051909182917fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80908290a35080600060016101000a8154816001600160a01b0302191690836001600160a01b03160217905550600060019054906101000a90046001600160a01b03166001600160a01b03166358f25c506040518163ffffffff1660e01b815260040160206040518083038186803b158015620000fe57600080fd5b505afa15801562000113573d6000803e3d6000fd5b505050506040513d60208110156200012a57600080fd5b5050506133b7806200013d6000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c8063a5d5db0c116100ad578063d8e51dfb11610071578063d8e51dfb146103eb578063e2ad6fe014610427578063e6abb5ae14610455578063ede4c0cc1461047b578063f851a4401461049f5761012c565b8063a5d5db0c146102fb578063b4f2a9cc14610327578063b9d2cc3014610355578063bbd7edc51461038b578063bfa25308146103e15761012c565b8063464b0485116100f4578063464b04851461023f57806347a7d1071461026b5780636321e20c146102975780638a0695fd1461029f5780639ee91d1f146102cd5761012c565b80630e496ef3146101315780631a7a4eb4146101815780632abaf14e146101c1578063318e7028146101ed578063350c35e914610213575b600080fd5b61016d6004803603608081101561014757600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356104a7565b604080519115158252519081900360200190f35b6101af6004803603604081101561019757600080fd5b506001600160a01b03813581169160200135166106e9565b60408051918252519081900360200190f35b61016d600480360360408110156101d757600080fd5b506001600160a01b038135169060200135610719565b61016d6004803603602081101561020357600080fd5b50356001600160a01b0316610add565b61016d6004803603604081101561022957600080fd5b506001600160a01b038135169060200135610c4f565b6101af6004803603604081101561025557600080fd5b506001600160a01b038135169060200135610eea565b61016d6004803603604081101561028157600080fd5b506001600160a01b038135169060200135611761565b61016d611a06565b6101af600480360360408110156102b557600080fd5b506001600160a01b0381358116916020013516611a0b565b61016d600480360360408110156102e357600080fd5b506001600160a01b0381358116916020013516611a36565b61016d6004803603604081101561031157600080fd5b506001600160a01b038135169060200135611b47565b61016d6004803603604081101561033d57600080fd5b506001600160a01b0381358116916020013516611ea8565b61016d6004803603606081101561036b57600080fd5b506001600160a01b03813581169160208101359091169060400135611ed9565b6103b9600480360360408110156103a157600080fd5b506001600160a01b0381358116916020013516611f97565b6040805194855260208501939093528383019190915215156060830152519081900360800190f35b6103e9611fdc565b005b6101af6004803603608081101561040157600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135612075565b6101af6004803603604081101561043d57600080fd5b506001600160a01b038135811691602001351661295c565b6103e96004803603602081101561046b57600080fd5b50356001600160a01b03166129c3565b610483612ac9565b604080516001600160a01b039092168252519081900360200190f35b610483612add565b6000805460ff166104f4576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff19169055336001600160a01b038616146105455760405162461bcd60e51b81526004018080602001828103825260248152602001806132786024913960400191505060405180910390fd5b6001600160a01b03808616600090815260016020908152604080832093871683529290522060020154828110156105ad5760405162461bcd60e51b81526004018080602001828103825260228152602001806131ff6022913960400191505060405180910390fd5b6000806105ba8386612aec565b909250905060008260048111156105cd57fe5b146105d457fe5b6001600160a01b038089166000818152600160209081526040808320948b16835293815290839020600201849055825163d8dfeb4560e01b81529251610678938b938a93909263d8dfeb45926004808201939291829003018186803b15801561063c57600080fd5b505afa158015610650573d6000803e3d6000fd5b505050506040513d602081101561066657600080fd5b50516001600160a01b03169190612b12565b856001600160a01b0316876001600160a01b0316896001600160a01b03167f01d76d96d07104485e19bcce9463bb051a46eaa5d8cce043a1a9cbaeb2a7228e886040518082815260200191505060405180910390a4600193505050506000805460ff19166001179055949350505050565b6001600160a01b038083166000908152600160209081526040808320938516835292905220600201545b92915050565b6001600160a01b0382166000908152600160209081526040808320338452909152812060030154839060ff1661078b576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b6107936130d7565b600084116107e8576040805162461bcd60e51b815260206004820152601860248201527f4552525f465245455f434f4c4c41544552414c5f5a45524f0000000000000000604482015290519081900360640190fd5b6001600160a01b0385166000908152600160208181526040808420338552825292839020835160808101855281548152928101549183019190915260028101549282018390526003015460ff16151560608201529085111561087b5760405162461bcd60e51b81526004018080602001828103825260228152602001806131ff6022913960400191505060405180910390fd5b610889816040015186612aec565b608084018190528382600481111561089d57fe5b60048111156108a857fe5b90525060009050825160048111156108bc57fe5b146108c357fe5b8051156109ac576108de863384608001518460000151612075565b604083810191909152600054815163351da44160e21b81526001600160a01b03898116600483015292516101009092049092169163d4769104916024808301926020929190829003018186803b15801561093757600080fd5b505afa15801561094b573d6000803e3d6000fd5b505050506040513d602081101561096157600080fd5b505160208301819052604083015110156109ac5760405162461bcd60e51b81526004018080602001828103825260218152602001806131bc6021913960400191505060405180910390fd5b60808201516001600160a01b03871660009081526001602090815260408083203384528252909120600201919091558101516109e89086612b69565b60608401819052838260048111156109fc57fe5b6004811115610a0757fe5b9052506000905082516004811115610a1b57fe5b14610a6d576040805162461bcd60e51b815260206004820152601e60248201527f4552525f465245455f434f4c4c41544552414c5f4d4154485f4552524f520000604482015290519081900360640190fd5b60608201516001600160a01b03871660008181526001602081815260408084203380865290835293819020909201949094558051898152905191937f1eb814d29363ba0d496e4eeb821d6f2537310b83b36c70fb97ae141b41fa733c92918290030190a350600195945050505050565b6000816001600160a01b031663cab364f16040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1857600080fd5b505afa158015610b2c573d6000803e3d6000fd5b505050506040513d6020811015610b4257600080fd5b5051610b7f5760405162461bcd60e51b815260040180806020018281038252602181526020018061332a6021913960400191505060405180910390fd5b6001600160a01b038216600090815260016020908152604080832033845290915290206003015460ff1615610bec576040805162461bcd60e51b815260206004820152600e60248201526d22a9292fab20aaa62a2fa7a822a760911b604482015290519081900360640190fd5b6001600160a01b0382166000818152600160208181526040808420338086529252808420600301805460ff191690931790925590519092917fbe36feaa49d1f66b249db1d112a47d32073d1ce484020276d73790cad02be89091a3506001919050565b6001600160a01b0382166000908152600160209081526040808320338452909152812060030154839060ff16610cc1576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff16610d0d576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff1916905582610d69576040805162461bcd60e51b815260206004820152601c60248201527f4552525f57495448445241575f434f4c4c41544552414c5f5a45524f00000000604482015290519081900360640190fd5b6001600160a01b03841660009081526001602081815260408084203385529091529091200154831115610de3576040805162461bcd60e51b815260206004820181905260248201527f4552525f494e53554646494349454e545f465245455f434f4c4c41544552414c604482015290519081900360640190fd5b6001600160a01b0384166000908152600160208181526040808420338552909152822001548190610e149086612aec565b90925090506000826004811115610e2757fe5b14610e2e57fe5b6001600160a01b03861660008181526001602081815260408084203380865290835293819020909201859055815163d8dfeb4560e01b81529151610e90948a93909263d8dfeb4592600480840193829003018186803b15801561063c57600080fd5b60408051868152905133916001600160a01b038916917f1607da8e9144035d8537941425741e9e3569c81d34a7f8e0c5c44635dc7169219181900360200190a3600193505050506000805460ff1916600117905592915050565b6000610ef4613108565b60008311610f335760405162461bcd60e51b815260040180806020018281038252602281526020018061329c6022913960400191505060405180910390fd5b600060019054906101000a90046001600160a01b03166001600160a01b0316634ada90af6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8157600080fd5b505afa158015610f95573d6000803e3d6000fd5b505050506040513d6020811015610fab57600080fd5b505160a08201819052610fc2576000915050610713565b60008060019054906101000a90046001600160a01b03166001600160a01b0316637dc0d1d06040518163ffffffff1660e01b815260040160206040518083038186803b15801561101157600080fd5b505afa158015611025573d6000803e3d6000fd5b505050506040513d602081101561103b57600080fd5b505160408051636f307dc360e01b815290519192506001600160a01b038084169263f8d71a119291891691636f307dc3916004808301926020929190829003018186803b15801561108b57600080fd5b505afa15801561109f573d6000803e3d6000fd5b505050506040513d60208110156110b557600080fd5b5051604080516395d89b4160e01b815290516001600160a01b03909216916395d89b4191600480820192600092909190829003018186803b1580156110f957600080fd5b505afa15801561110d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561113657600080fd5b8101908080516040519392919084600160201b82111561115557600080fd5b90830190602082018581111561116a57600080fd5b8251600160201b81118282018810171561118357600080fd5b82525081516020918201929091019080838360005b838110156111b0578181015183820152602001611198565b50505050905090810190601f1680156111dd5780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611230578181015183820152602001611218565b50505050905090810190601f16801561125d5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561127a57600080fd5b505afa15801561128e573d6000803e3d6000fd5b505050506040513d60208110156112a457600080fd5b50516101008301526040805163d8dfeb4560e01b815290516001600160a01b038084169263f8d71a11929189169163d8dfeb4591600480820192602092909190829003018186803b1580156112f857600080fd5b505afa15801561130c573d6000803e3d6000fd5b505050506040513d602081101561132257600080fd5b5051604080516395d89b4160e01b815290516001600160a01b03909216916395d89b4191600480820192600092909190829003018186803b15801561136657600080fd5b505afa15801561137a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156113a357600080fd5b8101908080516040519392919084600160201b8211156113c257600080fd5b9083019060208201858111156113d757600080fd5b8251600160201b8111828201881017156113f057600080fd5b82525081516020918201929091019080838360005b8381101561141d578181015183820152602001611405565b50505050905090810190601f16801561144a5780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561149d578181015183820152602001611485565b50505050905090810190601f1680156114ca5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156114e757600080fd5b505afa1580156114fb573d6000803e3d6000fd5b505050506040513d602081101561151157600080fd5b5051608083015260408051602081810183528682528251808201845260a086015181528351918201909352610100850151815261154e9290612b8f565b60c084018190528382600481111561156257fe5b600481111561156d57fe5b905250600090508251600481111561158157fe5b146115bd5760405162461bcd60e51b81526004018080602001828103825260288152602001806132e16028913960400191505060405180910390fd5b6115dd8260c0015160405180602001604052808560800151815250612be1565b60208401819052838260048111156115f157fe5b60048111156115fc57fe5b905250600090508251600481111561161057fe5b1461164c5760405162461bcd60e51b81526004018080602001828103825260288152602001806132e16028913960400191505060405180910390fd5b846001600160a01b031663b2bc5ef96040518163ffffffff1660e01b815260040160206040518083038186803b15801561168557600080fd5b505afa158015611699573d6000803e3d6000fd5b505050506040513d60208110156116af57600080fd5b505160608301819052600114611749576116d58260200151600001518360600151612c9a565b60408401819052838260048111156116e957fe5b60048111156116f457fe5b905250600090508251600481111561170857fe5b146117445760405162461bcd60e51b81526004018080602001828103825260288152602001806132e16028913960400191505060405180910390fd5b611755565b60208201515160408301525b50604001519392505050565b6001600160a01b0382166000908152600160209081526040808320338452909152812060030154839060ff166117d3576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60008311611828576040805162461bcd60e51b815260206004820152601860248201527f4552525f4c4f434b5f434f4c4c41544552414c5f5a45524f0000000000000000604482015290519081900360640190fd5b6001600160a01b03841660009081526001602081815260408084203385528252928390208351608081018552815481529281015491830182905260028101549383019390935260039092015460ff1615156060820152908411156118d3576040805162461bcd60e51b815260206004820181905260248201527f4552525f494e53554646494349454e545f465245455f434f4c4c41544552414c604482015290519081900360640190fd5b6000806118e4836040015187612b69565b909250905060008260048111156118f757fe5b14611949576040805162461bcd60e51b815260206004820152601e60248201527f4552525f4c4f434b5f434f4c4c41544552414c5f4d4154485f4552524f520000604482015290519081900360640190fd5b6001600160a01b03871660009081526001602090815260408083203384528252822060020183905584015161197e9088612aec565b9093509050600083600481111561199157fe5b1461199857fe5b6001600160a01b0388166000818152600160208181526040808420338086529083529381902090920185905581518b815291519293927f5dece52d6e464edb81a56c0ff16f6db48378690286920d6db39d387000064de69281900390910190a3506001979650505050505050565b600181565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0380831660009081526001602081815260408084209486168452938152838320845160808101865281548152928101549183019190915260028101549382019390935260039092015460ff16158015606084015290919080611a9e57508051155b15611aad576000915050610713565b6000611ab9858561295c565b600080546040805163351da44160e21b81526001600160a01b038a8116600483015291519495509293610100909204169163d4769104916024808301926020929190829003018186803b158015611b0f57600080fd5b505afa158015611b23573d6000803e3d6000fd5b505050506040513d6020811015611b3957600080fd5b505190911095945050505050565b6001600160a01b0382166000908152600160209081526040808320338452909152812060030154839060ff16611bb9576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff16611c05576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff1916905582611c61576040805162461bcd60e51b815260206004820152601b60248201527f4552525f4445504f5349545f434f4c4c41544552414c5f5a45524f0000000000604482015290519081900360640190fd5b600060019054906101000a90046001600160a01b03166001600160a01b031663ce8f6d3e856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611cc357600080fd5b505afa158015611cd7573d6000803e3d6000fd5b505050506040513d6020811015611ced57600080fd5b5051611d2a5760405162461bcd60e51b81526004018080602001828103825260228152602001806131dd6022913960400191505060405180910390fd5b6001600160a01b0384166000908152600160208181526040808420338552909152822001548190611d5b9086612b69565b90925090506000826004811115611d6e57fe5b14611daa5760405162461bcd60e51b81526004018080602001828103825260218152602001806132576021913960400191505060405180910390fd5b6001600160a01b03861660008181526001602081815260408084203380865290835293819020909201859055815163d8dfeb4560e01b81529151611e4e9430938b93919263d8dfeb4592600480840193919291829003018186803b158015611e1157600080fd5b505afa158015611e25573d6000803e3d6000fd5b505050506040513d6020811015611e3b57600080fd5b50516001600160a01b0316929190612cc5565b60408051868152905133916001600160a01b038916917fef12f18e2b6578b91b3c852c423ca8ee530f65f20f770e62a7ce8aa08e1ab7779181900360200190a3600193505050506000805460ff1916600117905592915050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152206003015460ff1690565b6000336001600160a01b03851614611f225760405162461bcd60e51b81526004018080602001828103825260218152602001806133096021913960400191505060405180910390fd5b6001600160a01b0384811660008181526001602090815260408083209488168084529482529182902080549087905582518181529182018790528251909493927ff2d27c8f0e872c6ed429c5d25278ae6023ae9cc5f788a0fd39b66fb738f8f45c928290030190a360019150505b9392505050565b6001600160a01b039182166000908152600160208181526040808420949095168352929092529190912080549181015460028201546003909201549293909260ff1690565b6002546001600160a01b0316331461202b576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b6002546040516000916001600160a01b0316907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80908390a3600280546001600160a01b0319169055565b600061207f613161565b6001600160a01b0380871660009081526001602090815260408083209389168352929052206003015460ff166120f1576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b83612100576000915050612954565b6000831161213f5760405162461bcd60e51b81526004018080602001828103825260368152602001806132216036913960400191505060405180910390fd5b60008060019054906101000a90046001600160a01b03166001600160a01b0316637dc0d1d06040518163ffffffff1660e01b815260040160206040518083038186803b15801561218e57600080fd5b505afa1580156121a2573d6000803e3d6000fd5b505050506040513d60208110156121b857600080fd5b50516040805163d8dfeb4560e01b815290519192506001600160a01b038084169263f8d71a1192918b169163d8dfeb45916004808301926020929190829003018186803b15801561220857600080fd5b505afa15801561221c573d6000803e3d6000fd5b505050506040513d602081101561223257600080fd5b5051604080516395d89b4160e01b815290516001600160a01b03909216916395d89b4191600480820192600092909190829003018186803b15801561227657600080fd5b505afa15801561228a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156122b357600080fd5b8101908080516040519392919084600160201b8211156122d257600080fd5b9083019060208201858111156122e757600080fd5b8251600160201b81118282018810171561230057600080fd5b82525081516020918201929091019080838360005b8381101561232d578181015183820152602001612315565b50505050905090810190601f16801561235a5780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156123ad578181015183820152602001612395565b50505050905090810190601f1680156123da5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156123f757600080fd5b505afa15801561240b573d6000803e3d6000fd5b505050506040513d602081101561242157600080fd5b505160208381019190915260408051636f307dc360e01b815290516001600160a01b038085169363f8d71a1193918c1692636f307dc3926004808201939291829003018186803b15801561247457600080fd5b505afa158015612488573d6000803e3d6000fd5b505050506040513d602081101561249e57600080fd5b5051604080516395d89b4160e01b815290516001600160a01b03909216916395d89b4191600480820192600092909190829003018186803b1580156124e257600080fd5b505afa1580156124f6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561251f57600080fd5b8101908080516040519392919084600160201b82111561253e57600080fd5b90830190602082018581111561255357600080fd5b8251600160201b81118282018810171561256c57600080fd5b82525081516020918201929091019080838360005b83811015612599578181015183820152602001612581565b50505050905090810190601f1680156125c65780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612619578181015183820152602001612601565b50505050905090810190601f1680156126465780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561266357600080fd5b505afa158015612677573d6000803e3d6000fd5b505050506040513d602081101561268d57600080fd5b50516101208301526040805163b2bc5ef960e01b815290516001600160a01b0389169163b2bc5ef9916004808301926020929190829003018186803b1580156126d557600080fd5b505afa1580156126e9573d6000803e3d6000fd5b505050506040513d60208110156126ff57600080fd5b5051604083018190526001146127915761271d858360400151612d25565b60e084018190528382600481111561273157fe5b600481111561273c57fe5b905250600090508251600481111561275057fe5b1461278c5760405162461bcd60e51b815260040180806020018281038252603781526020018061334b6037913960400191505060405180910390fd5b612799565b60e082018590525b604080516020808201835260e08501518252825180820190935284015182526127c191612d64565b60c08401819052838260048111156127d557fe5b60048111156127e057fe5b90525060009050825160048111156127f457fe5b146128305760405162461bcd60e51b815260040180806020018281038252603781526020018061334b6037913960400191505060405180910390fd5b61285b6040518060200160405280868152506040518060200160405280856101200151815250612d64565b608084018190528382600481111561286f57fe5b600481111561287a57fe5b905250600090508251600481111561288e57fe5b146128ca5760405162461bcd60e51b815260040180806020018281038252603781526020018061334b6037913960400191505060405180910390fd5b6128dc8260c001518360800151612be1565b60a08401819052838260048111156128f057fe5b60048111156128fb57fe5b905250600090508251600481111561290f57fe5b1461294b5760405162461bcd60e51b815260040180806020018281038252603781526020018061334b6037913960400191505060405180910390fd5b5060a001515190505b949350505050565b6001600160a01b038083166000908152600160208181526040808420948616845293815283832084516080810186528154808252938201549281019290925260028101549482018590526003015460ff161515606082015291926129549186918691612075565b6002546001600160a01b03163314612a12576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b6001600160a01b038116612a6d576040805162461bcd60e51b815260206004820152601a60248201527f4552525f5345545f41444d494e5f5a45524f5f41444452455353000000000000604482015290519081900360640190fd5b6002546040516001600160a01b038084169216907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf8090600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b60005461010090046001600160a01b031681565b6002546001600160a01b031681565b600080838311612b03575060009050818303612b0b565b506003905060005b9250929050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612b64908490612e4e565b505050565b600080838301848110612b8157600092509050612b0b565b600260009250925050612b0b565b6000612b996131a8565b600080612ba68787612d64565b90925090506000826004811115612bb957fe5b14612bc8579092509050612bd9565b612bd28186612d64565b9350935050505b935093915050565b6000612beb6131a8565b600080612c048660000151670de0b6b3a7640000612d25565b90925090506000826004811115612c1757fe5b14612c3657506040805160208101909152600081529092509050612b0b565b600080612c47838860000151612c9a565b90925090506000826004811115612c5a57fe5b14612c7d5781604051806020016040528060008152509550955050505050612b0b565b604080516020810190915290815260009890975095505050505050565b60008082612cae5750600190506000612b0b565b6000838581612cb957fe5b04915091509250929050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612d1f908590612e4e565b50505050565b60008083612d3857506000905080612b0b565b83830283858281612d4557fe5b0414612d5957600260009250925050612b0b565b600092509050612b0b565b6000612d6e6131a8565b600080612d8386600001518660000151612d25565b90925090506000826004811115612d9657fe5b14612db557506040805160208101909152600081529092509050612b0b565b600080612dca6706f05b59d3b2000084612b69565b90925090506000826004811115612ddd57fe5b14612e005781604051806020016040528060008152509550955050505050612b0b565b600080612e1583670de0b6b3a7640000612c9a565b90925090506000826004811115612e2857fe5b14612e2f57fe5b604080516020810190915290815260009a909950975050505050505050565b6000612e9083836040518060400160405280601d81526020017f4552525f534146455f45524332305f4c4f575f4c4556454c5f43414c4c000000815250612f02565b805190915015612b6457808060200190516020811015612eaf57600080fd5b5051612b64576040805162461bcd60e51b815260206004820152601e60248201527f4552525f534146455f45524332305f45524332305f4f5045524154494f4e0000604482015290519081900360640190fd5b6060612f16846001600160a01b031661309e565b612f515760405162461bcd60e51b81526004018080602001828103825260238152602001806132be6023913960400191505060405180910390fd5b600080856001600160a01b0316856040518082805190602001908083835b60208310612f8e5780518252601f199092019160209182019101612f6f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612ff0576040519150601f19603f3d011682016040523d82523d6000602084013e612ff5565b606091505b50915091508115613009579150611f909050565b8051156130195780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561306357818101518382015260200161304b565b50505050905090810190601f1680156130905780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612954575050151592915050565b6040805160a081019091528060005b8152602001600081526020016000815260200160008152602001600081525090565b60408051610120810190915280600081526020016131246131a8565b81526020016000815260200160008152602001600081526020016000815260200161314d6131a8565b815260200160008152602001600081525090565b60408051610160810190915280600081526020016000815260200160008152602001600081526020016131926131a8565b815260200161319f6131a8565b81526020016130e65b604051806020016040528060008152509056fe4552525f42454c4f575f434f4c4c41544552414c495a4154494f4e5f524154494f4552525f4445504f5349545f434f4c4c41544552414c5f4e4f545f414c4c4f5745444552525f494e53554646494349454e545f4c4f434b45445f434f4c4c41544552414c4552525f4745545f4859504f544845544943414c5f434f4c4c41544552414c495a4154494f4e5f524154494f5f444542545f5a45524f4552525f4445504f5349545f434f4c4c41544552414c5f4d4154485f4552524f524552525f434c555443485f434f4c4c41544552414c5f4e4f545f415554484f52495a45444552525f4745545f434c5554434841424c455f434f4c4c41544552414c5f5a45524f4552525f534146455f45524332305f43414c4c5f544f5f4e4f4e5f434f4e54524143544552525f4745545f434c5554434841424c455f434f4c4c41544552414c5f4d4154485f4552524f524552525f5345545f5641554c545f444542545f4e4f545f415554484f52495a45444552525f4f50454e5f5641554c545f4659544f4b454e5f494e5350454354494f4e4552525f4745545f4859504f544845544943414c5f434f4c4c41544552414c495a4154494f4e5f524154494f5f4d4154485f4552524f52a2646970667358221220928357a59c778e5f8d069b600a19b817e5393c5184a7792ffe7f0903b50afcd064736f6c63430007060033000000000000000000000000ed4348fc8b1b634b3a0eadabfd32530046b89c60
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061012c5760003560e01c8063a5d5db0c116100ad578063d8e51dfb11610071578063d8e51dfb146103eb578063e2ad6fe014610427578063e6abb5ae14610455578063ede4c0cc1461047b578063f851a4401461049f5761012c565b8063a5d5db0c146102fb578063b4f2a9cc14610327578063b9d2cc3014610355578063bbd7edc51461038b578063bfa25308146103e15761012c565b8063464b0485116100f4578063464b04851461023f57806347a7d1071461026b5780636321e20c146102975780638a0695fd1461029f5780639ee91d1f146102cd5761012c565b80630e496ef3146101315780631a7a4eb4146101815780632abaf14e146101c1578063318e7028146101ed578063350c35e914610213575b600080fd5b61016d6004803603608081101561014757600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356104a7565b604080519115158252519081900360200190f35b6101af6004803603604081101561019757600080fd5b506001600160a01b03813581169160200135166106e9565b60408051918252519081900360200190f35b61016d600480360360408110156101d757600080fd5b506001600160a01b038135169060200135610719565b61016d6004803603602081101561020357600080fd5b50356001600160a01b0316610add565b61016d6004803603604081101561022957600080fd5b506001600160a01b038135169060200135610c4f565b6101af6004803603604081101561025557600080fd5b506001600160a01b038135169060200135610eea565b61016d6004803603604081101561028157600080fd5b506001600160a01b038135169060200135611761565b61016d611a06565b6101af600480360360408110156102b557600080fd5b506001600160a01b0381358116916020013516611a0b565b61016d600480360360408110156102e357600080fd5b506001600160a01b0381358116916020013516611a36565b61016d6004803603604081101561031157600080fd5b506001600160a01b038135169060200135611b47565b61016d6004803603604081101561033d57600080fd5b506001600160a01b0381358116916020013516611ea8565b61016d6004803603606081101561036b57600080fd5b506001600160a01b03813581169160208101359091169060400135611ed9565b6103b9600480360360408110156103a157600080fd5b506001600160a01b0381358116916020013516611f97565b6040805194855260208501939093528383019190915215156060830152519081900360800190f35b6103e9611fdc565b005b6101af6004803603608081101561040157600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135612075565b6101af6004803603604081101561043d57600080fd5b506001600160a01b038135811691602001351661295c565b6103e96004803603602081101561046b57600080fd5b50356001600160a01b03166129c3565b610483612ac9565b604080516001600160a01b039092168252519081900360200190f35b610483612add565b6000805460ff166104f4576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff19169055336001600160a01b038616146105455760405162461bcd60e51b81526004018080602001828103825260248152602001806132786024913960400191505060405180910390fd5b6001600160a01b03808616600090815260016020908152604080832093871683529290522060020154828110156105ad5760405162461bcd60e51b81526004018080602001828103825260228152602001806131ff6022913960400191505060405180910390fd5b6000806105ba8386612aec565b909250905060008260048111156105cd57fe5b146105d457fe5b6001600160a01b038089166000818152600160209081526040808320948b16835293815290839020600201849055825163d8dfeb4560e01b81529251610678938b938a93909263d8dfeb45926004808201939291829003018186803b15801561063c57600080fd5b505afa158015610650573d6000803e3d6000fd5b505050506040513d602081101561066657600080fd5b50516001600160a01b03169190612b12565b856001600160a01b0316876001600160a01b0316896001600160a01b03167f01d76d96d07104485e19bcce9463bb051a46eaa5d8cce043a1a9cbaeb2a7228e886040518082815260200191505060405180910390a4600193505050506000805460ff19166001179055949350505050565b6001600160a01b038083166000908152600160209081526040808320938516835292905220600201545b92915050565b6001600160a01b0382166000908152600160209081526040808320338452909152812060030154839060ff1661078b576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b6107936130d7565b600084116107e8576040805162461bcd60e51b815260206004820152601860248201527f4552525f465245455f434f4c4c41544552414c5f5a45524f0000000000000000604482015290519081900360640190fd5b6001600160a01b0385166000908152600160208181526040808420338552825292839020835160808101855281548152928101549183019190915260028101549282018390526003015460ff16151560608201529085111561087b5760405162461bcd60e51b81526004018080602001828103825260228152602001806131ff6022913960400191505060405180910390fd5b610889816040015186612aec565b608084018190528382600481111561089d57fe5b60048111156108a857fe5b90525060009050825160048111156108bc57fe5b146108c357fe5b8051156109ac576108de863384608001518460000151612075565b604083810191909152600054815163351da44160e21b81526001600160a01b03898116600483015292516101009092049092169163d4769104916024808301926020929190829003018186803b15801561093757600080fd5b505afa15801561094b573d6000803e3d6000fd5b505050506040513d602081101561096157600080fd5b505160208301819052604083015110156109ac5760405162461bcd60e51b81526004018080602001828103825260218152602001806131bc6021913960400191505060405180910390fd5b60808201516001600160a01b03871660009081526001602090815260408083203384528252909120600201919091558101516109e89086612b69565b60608401819052838260048111156109fc57fe5b6004811115610a0757fe5b9052506000905082516004811115610a1b57fe5b14610a6d576040805162461bcd60e51b815260206004820152601e60248201527f4552525f465245455f434f4c4c41544552414c5f4d4154485f4552524f520000604482015290519081900360640190fd5b60608201516001600160a01b03871660008181526001602081815260408084203380865290835293819020909201949094558051898152905191937f1eb814d29363ba0d496e4eeb821d6f2537310b83b36c70fb97ae141b41fa733c92918290030190a350600195945050505050565b6000816001600160a01b031663cab364f16040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1857600080fd5b505afa158015610b2c573d6000803e3d6000fd5b505050506040513d6020811015610b4257600080fd5b5051610b7f5760405162461bcd60e51b815260040180806020018281038252602181526020018061332a6021913960400191505060405180910390fd5b6001600160a01b038216600090815260016020908152604080832033845290915290206003015460ff1615610bec576040805162461bcd60e51b815260206004820152600e60248201526d22a9292fab20aaa62a2fa7a822a760911b604482015290519081900360640190fd5b6001600160a01b0382166000818152600160208181526040808420338086529252808420600301805460ff191690931790925590519092917fbe36feaa49d1f66b249db1d112a47d32073d1ce484020276d73790cad02be89091a3506001919050565b6001600160a01b0382166000908152600160209081526040808320338452909152812060030154839060ff16610cc1576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff16610d0d576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff1916905582610d69576040805162461bcd60e51b815260206004820152601c60248201527f4552525f57495448445241575f434f4c4c41544552414c5f5a45524f00000000604482015290519081900360640190fd5b6001600160a01b03841660009081526001602081815260408084203385529091529091200154831115610de3576040805162461bcd60e51b815260206004820181905260248201527f4552525f494e53554646494349454e545f465245455f434f4c4c41544552414c604482015290519081900360640190fd5b6001600160a01b0384166000908152600160208181526040808420338552909152822001548190610e149086612aec565b90925090506000826004811115610e2757fe5b14610e2e57fe5b6001600160a01b03861660008181526001602081815260408084203380865290835293819020909201859055815163d8dfeb4560e01b81529151610e90948a93909263d8dfeb4592600480840193829003018186803b15801561063c57600080fd5b60408051868152905133916001600160a01b038916917f1607da8e9144035d8537941425741e9e3569c81d34a7f8e0c5c44635dc7169219181900360200190a3600193505050506000805460ff1916600117905592915050565b6000610ef4613108565b60008311610f335760405162461bcd60e51b815260040180806020018281038252602281526020018061329c6022913960400191505060405180910390fd5b600060019054906101000a90046001600160a01b03166001600160a01b0316634ada90af6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8157600080fd5b505afa158015610f95573d6000803e3d6000fd5b505050506040513d6020811015610fab57600080fd5b505160a08201819052610fc2576000915050610713565b60008060019054906101000a90046001600160a01b03166001600160a01b0316637dc0d1d06040518163ffffffff1660e01b815260040160206040518083038186803b15801561101157600080fd5b505afa158015611025573d6000803e3d6000fd5b505050506040513d602081101561103b57600080fd5b505160408051636f307dc360e01b815290519192506001600160a01b038084169263f8d71a119291891691636f307dc3916004808301926020929190829003018186803b15801561108b57600080fd5b505afa15801561109f573d6000803e3d6000fd5b505050506040513d60208110156110b557600080fd5b5051604080516395d89b4160e01b815290516001600160a01b03909216916395d89b4191600480820192600092909190829003018186803b1580156110f957600080fd5b505afa15801561110d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561113657600080fd5b8101908080516040519392919084600160201b82111561115557600080fd5b90830190602082018581111561116a57600080fd5b8251600160201b81118282018810171561118357600080fd5b82525081516020918201929091019080838360005b838110156111b0578181015183820152602001611198565b50505050905090810190601f1680156111dd5780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611230578181015183820152602001611218565b50505050905090810190601f16801561125d5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561127a57600080fd5b505afa15801561128e573d6000803e3d6000fd5b505050506040513d60208110156112a457600080fd5b50516101008301526040805163d8dfeb4560e01b815290516001600160a01b038084169263f8d71a11929189169163d8dfeb4591600480820192602092909190829003018186803b1580156112f857600080fd5b505afa15801561130c573d6000803e3d6000fd5b505050506040513d602081101561132257600080fd5b5051604080516395d89b4160e01b815290516001600160a01b03909216916395d89b4191600480820192600092909190829003018186803b15801561136657600080fd5b505afa15801561137a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156113a357600080fd5b8101908080516040519392919084600160201b8211156113c257600080fd5b9083019060208201858111156113d757600080fd5b8251600160201b8111828201881017156113f057600080fd5b82525081516020918201929091019080838360005b8381101561141d578181015183820152602001611405565b50505050905090810190601f16801561144a5780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561149d578181015183820152602001611485565b50505050905090810190601f1680156114ca5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156114e757600080fd5b505afa1580156114fb573d6000803e3d6000fd5b505050506040513d602081101561151157600080fd5b5051608083015260408051602081810183528682528251808201845260a086015181528351918201909352610100850151815261154e9290612b8f565b60c084018190528382600481111561156257fe5b600481111561156d57fe5b905250600090508251600481111561158157fe5b146115bd5760405162461bcd60e51b81526004018080602001828103825260288152602001806132e16028913960400191505060405180910390fd5b6115dd8260c0015160405180602001604052808560800151815250612be1565b60208401819052838260048111156115f157fe5b60048111156115fc57fe5b905250600090508251600481111561161057fe5b1461164c5760405162461bcd60e51b81526004018080602001828103825260288152602001806132e16028913960400191505060405180910390fd5b846001600160a01b031663b2bc5ef96040518163ffffffff1660e01b815260040160206040518083038186803b15801561168557600080fd5b505afa158015611699573d6000803e3d6000fd5b505050506040513d60208110156116af57600080fd5b505160608301819052600114611749576116d58260200151600001518360600151612c9a565b60408401819052838260048111156116e957fe5b60048111156116f457fe5b905250600090508251600481111561170857fe5b146117445760405162461bcd60e51b81526004018080602001828103825260288152602001806132e16028913960400191505060405180910390fd5b611755565b60208201515160408301525b50604001519392505050565b6001600160a01b0382166000908152600160209081526040808320338452909152812060030154839060ff166117d3576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60008311611828576040805162461bcd60e51b815260206004820152601860248201527f4552525f4c4f434b5f434f4c4c41544552414c5f5a45524f0000000000000000604482015290519081900360640190fd5b6001600160a01b03841660009081526001602081815260408084203385528252928390208351608081018552815481529281015491830182905260028101549383019390935260039092015460ff1615156060820152908411156118d3576040805162461bcd60e51b815260206004820181905260248201527f4552525f494e53554646494349454e545f465245455f434f4c4c41544552414c604482015290519081900360640190fd5b6000806118e4836040015187612b69565b909250905060008260048111156118f757fe5b14611949576040805162461bcd60e51b815260206004820152601e60248201527f4552525f4c4f434b5f434f4c4c41544552414c5f4d4154485f4552524f520000604482015290519081900360640190fd5b6001600160a01b03871660009081526001602090815260408083203384528252822060020183905584015161197e9088612aec565b9093509050600083600481111561199157fe5b1461199857fe5b6001600160a01b0388166000818152600160208181526040808420338086529083529381902090920185905581518b815291519293927f5dece52d6e464edb81a56c0ff16f6db48378690286920d6db39d387000064de69281900390910190a3506001979650505050505050565b600181565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0380831660009081526001602081815260408084209486168452938152838320845160808101865281548152928101549183019190915260028101549382019390935260039092015460ff16158015606084015290919080611a9e57508051155b15611aad576000915050610713565b6000611ab9858561295c565b600080546040805163351da44160e21b81526001600160a01b038a8116600483015291519495509293610100909204169163d4769104916024808301926020929190829003018186803b158015611b0f57600080fd5b505afa158015611b23573d6000803e3d6000fd5b505050506040513d6020811015611b3957600080fd5b505190911095945050505050565b6001600160a01b0382166000908152600160209081526040808320338452909152812060030154839060ff16611bb9576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff16611c05576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff1916905582611c61576040805162461bcd60e51b815260206004820152601b60248201527f4552525f4445504f5349545f434f4c4c41544552414c5f5a45524f0000000000604482015290519081900360640190fd5b600060019054906101000a90046001600160a01b03166001600160a01b031663ce8f6d3e856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611cc357600080fd5b505afa158015611cd7573d6000803e3d6000fd5b505050506040513d6020811015611ced57600080fd5b5051611d2a5760405162461bcd60e51b81526004018080602001828103825260228152602001806131dd6022913960400191505060405180910390fd5b6001600160a01b0384166000908152600160208181526040808420338552909152822001548190611d5b9086612b69565b90925090506000826004811115611d6e57fe5b14611daa5760405162461bcd60e51b81526004018080602001828103825260218152602001806132576021913960400191505060405180910390fd5b6001600160a01b03861660008181526001602081815260408084203380865290835293819020909201859055815163d8dfeb4560e01b81529151611e4e9430938b93919263d8dfeb4592600480840193919291829003018186803b158015611e1157600080fd5b505afa158015611e25573d6000803e3d6000fd5b505050506040513d6020811015611e3b57600080fd5b50516001600160a01b0316929190612cc5565b60408051868152905133916001600160a01b038916917fef12f18e2b6578b91b3c852c423ca8ee530f65f20f770e62a7ce8aa08e1ab7779181900360200190a3600193505050506000805460ff1916600117905592915050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152206003015460ff1690565b6000336001600160a01b03851614611f225760405162461bcd60e51b81526004018080602001828103825260218152602001806133096021913960400191505060405180910390fd5b6001600160a01b0384811660008181526001602090815260408083209488168084529482529182902080549087905582518181529182018790528251909493927ff2d27c8f0e872c6ed429c5d25278ae6023ae9cc5f788a0fd39b66fb738f8f45c928290030190a360019150505b9392505050565b6001600160a01b039182166000908152600160208181526040808420949095168352929092529190912080549181015460028201546003909201549293909260ff1690565b6002546001600160a01b0316331461202b576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b6002546040516000916001600160a01b0316907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80908390a3600280546001600160a01b0319169055565b600061207f613161565b6001600160a01b0380871660009081526001602090815260408083209389168352929052206003015460ff166120f1576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b83612100576000915050612954565b6000831161213f5760405162461bcd60e51b81526004018080602001828103825260368152602001806132216036913960400191505060405180910390fd5b60008060019054906101000a90046001600160a01b03166001600160a01b0316637dc0d1d06040518163ffffffff1660e01b815260040160206040518083038186803b15801561218e57600080fd5b505afa1580156121a2573d6000803e3d6000fd5b505050506040513d60208110156121b857600080fd5b50516040805163d8dfeb4560e01b815290519192506001600160a01b038084169263f8d71a1192918b169163d8dfeb45916004808301926020929190829003018186803b15801561220857600080fd5b505afa15801561221c573d6000803e3d6000fd5b505050506040513d602081101561223257600080fd5b5051604080516395d89b4160e01b815290516001600160a01b03909216916395d89b4191600480820192600092909190829003018186803b15801561227657600080fd5b505afa15801561228a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156122b357600080fd5b8101908080516040519392919084600160201b8211156122d257600080fd5b9083019060208201858111156122e757600080fd5b8251600160201b81118282018810171561230057600080fd5b82525081516020918201929091019080838360005b8381101561232d578181015183820152602001612315565b50505050905090810190601f16801561235a5780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156123ad578181015183820152602001612395565b50505050905090810190601f1680156123da5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156123f757600080fd5b505afa15801561240b573d6000803e3d6000fd5b505050506040513d602081101561242157600080fd5b505160208381019190915260408051636f307dc360e01b815290516001600160a01b038085169363f8d71a1193918c1692636f307dc3926004808201939291829003018186803b15801561247457600080fd5b505afa158015612488573d6000803e3d6000fd5b505050506040513d602081101561249e57600080fd5b5051604080516395d89b4160e01b815290516001600160a01b03909216916395d89b4191600480820192600092909190829003018186803b1580156124e257600080fd5b505afa1580156124f6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561251f57600080fd5b8101908080516040519392919084600160201b82111561253e57600080fd5b90830190602082018581111561255357600080fd5b8251600160201b81118282018810171561256c57600080fd5b82525081516020918201929091019080838360005b83811015612599578181015183820152602001612581565b50505050905090810190601f1680156125c65780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612619578181015183820152602001612601565b50505050905090810190601f1680156126465780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561266357600080fd5b505afa158015612677573d6000803e3d6000fd5b505050506040513d602081101561268d57600080fd5b50516101208301526040805163b2bc5ef960e01b815290516001600160a01b0389169163b2bc5ef9916004808301926020929190829003018186803b1580156126d557600080fd5b505afa1580156126e9573d6000803e3d6000fd5b505050506040513d60208110156126ff57600080fd5b5051604083018190526001146127915761271d858360400151612d25565b60e084018190528382600481111561273157fe5b600481111561273c57fe5b905250600090508251600481111561275057fe5b1461278c5760405162461bcd60e51b815260040180806020018281038252603781526020018061334b6037913960400191505060405180910390fd5b612799565b60e082018590525b604080516020808201835260e08501518252825180820190935284015182526127c191612d64565b60c08401819052838260048111156127d557fe5b60048111156127e057fe5b90525060009050825160048111156127f457fe5b146128305760405162461bcd60e51b815260040180806020018281038252603781526020018061334b6037913960400191505060405180910390fd5b61285b6040518060200160405280868152506040518060200160405280856101200151815250612d64565b608084018190528382600481111561286f57fe5b600481111561287a57fe5b905250600090508251600481111561288e57fe5b146128ca5760405162461bcd60e51b815260040180806020018281038252603781526020018061334b6037913960400191505060405180910390fd5b6128dc8260c001518360800151612be1565b60a08401819052838260048111156128f057fe5b60048111156128fb57fe5b905250600090508251600481111561290f57fe5b1461294b5760405162461bcd60e51b815260040180806020018281038252603781526020018061334b6037913960400191505060405180910390fd5b5060a001515190505b949350505050565b6001600160a01b038083166000908152600160208181526040808420948616845293815283832084516080810186528154808252938201549281019290925260028101549482018590526003015460ff161515606082015291926129549186918691612075565b6002546001600160a01b03163314612a12576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b6001600160a01b038116612a6d576040805162461bcd60e51b815260206004820152601a60248201527f4552525f5345545f41444d494e5f5a45524f5f41444452455353000000000000604482015290519081900360640190fd5b6002546040516001600160a01b038084169216907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf8090600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b60005461010090046001600160a01b031681565b6002546001600160a01b031681565b600080838311612b03575060009050818303612b0b565b506003905060005b9250929050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612b64908490612e4e565b505050565b600080838301848110612b8157600092509050612b0b565b600260009250925050612b0b565b6000612b996131a8565b600080612ba68787612d64565b90925090506000826004811115612bb957fe5b14612bc8579092509050612bd9565b612bd28186612d64565b9350935050505b935093915050565b6000612beb6131a8565b600080612c048660000151670de0b6b3a7640000612d25565b90925090506000826004811115612c1757fe5b14612c3657506040805160208101909152600081529092509050612b0b565b600080612c47838860000151612c9a565b90925090506000826004811115612c5a57fe5b14612c7d5781604051806020016040528060008152509550955050505050612b0b565b604080516020810190915290815260009890975095505050505050565b60008082612cae5750600190506000612b0b565b6000838581612cb957fe5b04915091509250929050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612d1f908590612e4e565b50505050565b60008083612d3857506000905080612b0b565b83830283858281612d4557fe5b0414612d5957600260009250925050612b0b565b600092509050612b0b565b6000612d6e6131a8565b600080612d8386600001518660000151612d25565b90925090506000826004811115612d9657fe5b14612db557506040805160208101909152600081529092509050612b0b565b600080612dca6706f05b59d3b2000084612b69565b90925090506000826004811115612ddd57fe5b14612e005781604051806020016040528060008152509550955050505050612b0b565b600080612e1583670de0b6b3a7640000612c9a565b90925090506000826004811115612e2857fe5b14612e2f57fe5b604080516020810190915290815260009a909950975050505050505050565b6000612e9083836040518060400160405280601d81526020017f4552525f534146455f45524332305f4c4f575f4c4556454c5f43414c4c000000815250612f02565b805190915015612b6457808060200190516020811015612eaf57600080fd5b5051612b64576040805162461bcd60e51b815260206004820152601e60248201527f4552525f534146455f45524332305f45524332305f4f5045524154494f4e0000604482015290519081900360640190fd5b6060612f16846001600160a01b031661309e565b612f515760405162461bcd60e51b81526004018080602001828103825260238152602001806132be6023913960400191505060405180910390fd5b600080856001600160a01b0316856040518082805190602001908083835b60208310612f8e5780518252601f199092019160209182019101612f6f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612ff0576040519150601f19603f3d011682016040523d82523d6000602084013e612ff5565b606091505b50915091508115613009579150611f909050565b8051156130195780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561306357818101518382015260200161304b565b50505050905090810190601f1680156130905780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612954575050151592915050565b6040805160a081019091528060005b8152602001600081526020016000815260200160008152602001600081525090565b60408051610120810190915280600081526020016131246131a8565b81526020016000815260200160008152602001600081526020016000815260200161314d6131a8565b815260200160008152602001600081525090565b60408051610160810190915280600081526020016000815260200160008152602001600081526020016131926131a8565b815260200161319f6131a8565b81526020016130e65b604051806020016040528060008152509056fe4552525f42454c4f575f434f4c4c41544552414c495a4154494f4e5f524154494f4552525f4445504f5349545f434f4c4c41544552414c5f4e4f545f414c4c4f5745444552525f494e53554646494349454e545f4c4f434b45445f434f4c4c41544552414c4552525f4745545f4859504f544845544943414c5f434f4c4c41544552414c495a4154494f4e5f524154494f5f444542545f5a45524f4552525f4445504f5349545f434f4c4c41544552414c5f4d4154485f4552524f524552525f434c555443485f434f4c4c41544552414c5f4e4f545f415554484f52495a45444552525f4745545f434c5554434841424c455f434f4c4c41544552414c5f5a45524f4552525f534146455f45524332305f43414c4c5f544f5f4e4f4e5f434f4e54524143544552525f4745545f434c5554434841424c455f434f4c4c41544552414c5f4d4154485f4552524f524552525f5345545f5641554c545f444542545f4e4f545f415554484f52495a45444552525f4f50454e5f5641554c545f4659544f4b454e5f494e5350454354494f4e4552525f4745545f4859504f544845544943414c5f434f4c4c41544552414c495a4154494f4e5f524154494f5f4d4154485f4552524f52a2646970667358221220928357a59c778e5f8d069b600a19b817e5393c5184a7792ffe7f0903b50afcd064736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ed4348fc8b1b634b3a0eadabfd32530046b89c60
-----Decoded View---------------
Arg [0] : fintroller_ (address): 0xED4348fC8B1B634b3A0eadabFD32530046B89C60
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000ed4348fc8b1b634b3a0eadabfd32530046b89c60
Deployed Bytecode Sourcemap
464:23318:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12730:1212;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;12730:1212:5;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;10557:230;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;10557:230:5;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;16543:1950;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;16543:1950:5;;;;;;;;:::i;20630:375::-;;;;;;;;;;;;;;;;-1:-1:-1;20630:375:5;-1:-1:-1;;;;;20630:375:5;;:::i;22578:1202::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;22578:1202:5;;;;;;;;:::i;2166:2418::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;2166:2418:5;;;;;;;;:::i;19008:1238::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;19008:1238:5;;;;;;;;:::i;705:42:7:-;;;:::i;10184:170:5:-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;10184:170:5;;;;;;;;;;:::i;11095:581::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;11095:581:5;;;;;;;;;;:::i;14538:1190::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;14538:1190:5;;;;;;;;:::i;11794:168::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;11794:168:5;;;;;;;;;;:::i;21500:566::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;21500:566:5;;;;;;;;;;;;;;;;;:::i;9553:491::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;9553:491:5;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1615:150:1;;;:::i;:::-;;6594:2787:5;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;6594:2787:5;;;;;;;;;;;;;;;;;;;;;;:::i;4908:342::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;4908:342:5;;;;;;;;;;:::i;1969:230:1:-;;;;;;;;;;;;;;;;-1:-1:-1;1969:230:1;-1:-1:-1;;;;;1969:230:1;;:::i;425:37:7:-;;;:::i;:::-;;;;-1:-1:-1;;;;;425:37:7;;;;;;;;;;;;;;182:20:3;;;:::i;12730:1212:5:-;12924:4;1817:10:21;;;;1809:41;;;;;-1:-1:-1;;;1809:41:21;;;;;;;;;;;;-1:-1:-1;;;1809:41:21;;;;;;;;;;;;;;;1942:5;1929:18;;-1:-1:-1;;1929:18:21;;;12997:10:5::1;-1:-1:-1::0;;;;;12997:30:5;::::1;;12989:79;;;;-1:-1:-1::0;;;12989:79:5::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;13180:24:5;;::::1;13153;13180::::0;;;:6:::1;:24;::::0;;;;;;;:34;;::::1;::::0;;;;;;:51:::1;;::::0;13249:36;;::::1;;13241:83;;;;-1:-1:-1::0;;;13241:83:5::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13393:17;13420:27:::0;13490:43:::1;13498:16;13516;13490:7;:43::i;:::-;13457:76:::0;;-1:-1:-1;13457:76:5;-1:-1:-1;13561:18:5::1;13550:7;:29;;;;;;;;;13543:37;;;;-1:-1:-1::0;;;;;13632:24:5;;::::1;;::::0;;;:6:::1;:24;::::0;;;;;;;:34;;::::1;::::0;;;;;;;;;:51:::1;;:73:::0;;;13769:20;;-1:-1:-1;;;13769:20:5;;;;:63:::1;::::0;13803:10;;13815:16;;13632:24;;13769:18:::1;::::0;:20:::1;::::0;;::::1;::::0;13632:24;13769:20;;;;;;13632:24;13769:20;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;13769:20:5;-1:-1:-1;;;;;13769:33:5::1;::::0;:63;:33:::1;:63::i;:::-;13886:8;-1:-1:-1::0;;;;;13848:65:5::1;13874:10;-1:-1:-1::0;;;;;13848:65:5::1;13865:7;-1:-1:-1::0;;;;;13848:65:5::1;;13896:16;13848:65;;;;;;;;;;;;;;;;;;13931:4;13924:11;;;;;2126:10:21::0;:17;;-1:-1:-1;;2126:17:21;2139:4;2126:17;;;12730:1212:5;;-1:-1:-1;;;;12730:1212:5:o;10557:230::-;-1:-1:-1;;;;;10729:24:5;;;10699:7;10729:24;;;:6;:24;;;;;;;;:34;;;;;;;;;:51;;;10557:230;;;;;:::o;16543:1950::-;-1:-1:-1;;;;;774:24:5;;16711:4;774:24;;;:6;:24;;;;;;;;799:10;774:36;;;;;;;:43;;;16685:7;;774:43;;766:74;;;;;-1:-1:-1;;;766:74:5;;;;;;;;;;;;-1:-1:-1;;;766:74:5;;;;;;;;;;;;;;;16731:35:::1;;:::i;:::-;16846:1;16827:16;:20;16819:57;;;::::0;;-1:-1:-1;;;16819:57:5;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;16956:24:5;::::1;16935:18;16956:24:::0;;;:6:::1;:24;::::0;;;;;;;16981:10:::1;16956:36:::0;;;;;;;;16935:57;;::::1;::::0;::::1;::::0;;;;;;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;;;;;;::::1;;::::0;::::1;;;;::::0;;;;;17010:42;-1:-1:-1;17010:42:5::1;17002:89;;;;-1:-1:-1::0;;;17002:89:5::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17234:49;17242:5;:22;;;17266:16;17234:7;:49::i;:::-;17206:24;::::0;::::1;17191:92:::0;;;17192:4;17191:92;::::1;::::0;::::1;;;;;;;;;;;;;;::::0;;-1:-1:-1;17316:18:5::1;::::0;-1:-1:-1;17300:12:5;;:34:::1;::::0;::::1;;;;;;;17293:42;;;;17437:10:::0;;:14;17433:562:::1;;17517:174;17572:7;17597:10;17625:4;:24;;;17667:5;:10;;;17517:37;:174::i;:::-;17467:47;::::0;;::::1;:224:::0;;;;17743:10:::1;::::0;:49;;-1:-1:-1;;;17743:49:5;;-1:-1:-1;;;;;17743:49:5;;::::1;;::::0;::::1;::::0;;;:10:::1;::::0;;::::1;::::0;;::::1;::::0;:40:::1;::::0;:49;;;;;::::1;::::0;;;;;;;;:10;:49;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;17743:49:5;::::1;17705:35:::0;::::1;:87:::0;;;17831:47:::1;::::0;::::1;::::0;:86:::1;;17806:178;;;;-1:-1:-1::0;;;17806:178:5::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18100:24;::::0;::::1;::::0;-1:-1:-1;;;;;18044:24:5;::::1;;::::0;;;:6:::1;:24;::::0;;;;;;;18069:10:::1;18044:36:::0;;;;;;;:53:::1;;:80:::0;;;;18183:20;::::1;::::0;18175:47:::1;::::0;18205:16;18175:7:::1;:47::i;:::-;18149:22;::::0;::::1;18134:88:::0;;;18135:4;18134:88;::::1;::::0;::::1;;;;;;;;;;;;;;::::0;;-1:-1:-1;18256:18:5::1;::::0;-1:-1:-1;18240:12:5;;:34:::1;::::0;::::1;;;;;;;18232:77;;;::::0;;-1:-1:-1;;;18232:77:5;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;18373:22;::::0;::::1;::::0;-1:-1:-1;;;;;18319:24:5;::::1;;::::0;;;:6:::1;:24;::::0;;;;;;;18344:10:::1;18319:36:::0;;;;;;;;;;:51;;::::1;:76:::0;;;;18411:53;;;;;;;18344:10;;18411:53:::1;::::0;;;;;;;::::1;-1:-1:-1::0;18482:4:5::1;::::0;16543:1950;-1:-1:-1;;;;;16543:1950:5:o;20630:375::-;20702:4;20726:7;-1:-1:-1;;;;;20726:17:5;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20726:19:5;20718:65;;;;-1:-1:-1;;;20718:65:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20801:24:5;;;;;;:6;:24;;;;;;;;20826:10;20801:36;;;;;;;:43;;;;;:52;20793:79;;;;;-1:-1:-1;;;20793:79:5;;;;;;;;;;;;-1:-1:-1;;;20793:79:5;;;;;;;;;;;;;;;-1:-1:-1;;;;;20882:24:5;;;;;;20928:4;20882:24;;;;;;;;20907:10;20882:36;;;;;;;;:43;;:50;;-1:-1:-1;;20882:50:5;;;;;;;20947:30;;20907:10;;20882:24;20947:30;;;-1:-1:-1;20994:4:5;20630:375;;;:::o;22578:1202::-;-1:-1:-1;;;;;774:24:5;;22771:4;774:24;;;:6;:24;;;;;;;;799:10;774:36;;;;;;;:43;;;22724:7;;774:43;;766:74;;;;;-1:-1:-1;;;766:74:5;;;;;;;;;;;;-1:-1:-1;;;766:74:5;;;;;;;;;;;;;;;1817:10:21::1;::::0;::::1;;1809:41;;;::::0;;-1:-1:-1;;;1809:41:21;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1809:41:21;;;;;;;;;;;;;::::1;;1942:5;1929:18:::0;;-1:-1:-1;;1929:18:21::1;::::0;;22841:20:5;22833:61:::2;;;::::0;;-1:-1:-1;;;22833:61:5;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;-1:-1:-1::0;;;;;22981:24:5;::::2;;::::0;;;:6:::2;:24;::::0;;;;;;;23006:10:::2;22981:36:::0;;;;;;;;:51:::2;::::0;:71;-1:-1:-1;22981:71:5::2;22960:150;;;::::0;;-1:-1:-1;;;22960:150:5;;::::2;;::::0;::::2;::::0;;;;;;;::::2;::::0;;;;;;;;;;;;;::::2;;-1:-1:-1::0;;;;;23261:24:5;::::2;23160:17;23261:24:::0;;;:6:::2;:24;::::0;;;;;;;23286:10:::2;23261:36:::0;;;;;;;:51:::2;::::0;23160:17;;23253:78:::2;::::0;23314:16;23253:7:::2;:78::i;:::-;23222:109:::0;;-1:-1:-1;23222:109:5;-1:-1:-1;23448:18:5::2;23437:7;:29;;;;;;;;;23430:37;;;;-1:-1:-1::0;;;;;23477:24:5;::::2;;::::0;;;:6:::2;:24;::::0;;;;;;;23502:10:::2;23477:36:::0;;;;;;;;;;:51;;::::2;:71:::0;;;23615:20;;-1:-1:-1;;;23615:20:5;;;;:63:::2;::::0;23661:16;;23477:24;;23615:18:::2;::::0;:20:::2;::::0;;::::2;::::0;;;;;;23477:24;23615:20;::::2;;::::0;::::2;;;;::::0;::::2;:63;23694:57;::::0;;;;;;;23722:10:::2;::::0;-1:-1:-1;;;;;23694:57:5;::::2;::::0;::::2;::::0;;;;::::2;::::0;;::::2;23769:4;23762:11;;;;-1:-1:-1::0;2126:10:21::1;:17:::0;;-1:-1:-1;;2126:17:21::1;2139:4;2126:17;::::0;;22578:1202:5;;-1:-1:-1;;22578:1202:5:o;2166:2418::-;2310:7;2333:44;;:::i;:::-;2451:1;2437:11;:15;2429:62;;;;-1:-1:-1;;;2429:62:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2630:10;;;;;;;;;-1:-1:-1;;;;;2630:10:5;-1:-1:-1;;;;;2630:39:5;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2630:41:5;2594:33;;;:77;;;2681;;2746:1;2739:8;;;;;2681:77;2829:33;2865:10;;;;;;;;;-1:-1:-1;;;;;2865:10:5;-1:-1:-1;;;;;2865:17:5;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2865:19:5;2949:20;;;-1:-1:-1;;;2949:20:5;;;;2865:19;;-1:-1:-1;;;;;;2925:23:5;;;;;;2949:18;;;;;;:20;;;;;2865:19;;2949:20;;;;;;;:18;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2949:20:5;:29;;;-1:-1:-1;;;2949:29:5;;;;-1:-1:-1;;;;;2949:27:5;;;;;;:29;;;;;;;;;;;;;;;:27;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2949:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2949:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2949:29:5;;;;;;-1:-1:-1;2949:29:5;;;;;;;;;;-1:-1:-1;2949:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2925:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2925:54:5;2894:28;;;:85;3106:20;;;-1:-1:-1;;;3106:20:5;;;;-1:-1:-1;;;;;3082:23:5;;;;;;3106:18;;;;;;:20;;;;;2925:54;;3106:20;;;;;;;;:18;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3106:20:5;:29;;;-1:-1:-1;;;3106:29:5;;;;-1:-1:-1;;;;;3106:27:5;;;;;;:29;;;;;;;;;;;;;;;:27;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3106:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;3106:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;3106:29:5;;;;;;-1:-1:-1;3106:29:5;;;;;;;;;;-1:-1:-1;3106:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3082:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3082:54:5;3051:28;;;:85;3255:30;;;3082:54;3255:30;;;;;;;;3299:52;;;;;;;3315:33;;;;3299:52;;3365:47;;;;;;;;3381:28;;;;3365:47;;3234:188;;3299:52;3234:7;:188::i;:::-;3216:14;;;3201:221;;;3202:4;3201:221;;;;;;;;;;;;;;;;;;;-1:-1:-1;3456:18:5;;-1:-1:-1;3440:12:5;;:34;;;;;;;;;3432:87;;;;-1:-1:-1;;;3432:87:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3665:105;3685:4;:14;;;3713:47;;;;;;;;3729:4;:28;;;3713:47;;;3665:6;:105::i;:::-;3622:39;;;3607:163;;;3608:4;3607:163;;;;;;;;;;;;;;;;;;;-1:-1:-1;3804:18:5;;-1:-1:-1;3788:12:5;;:34;;;;;;;;;3780:87;;;;-1:-1:-1;;;3780:87:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4019:7;-1:-1:-1;;;;;4019:33:5;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4019:35:5;3986:30;;;:68;;;4102:1;4068:35;4064:465;;4169:135;4194:4;:39;;;:48;;;4260:4;:30;;;4169:7;:135::i;:::-;4134:31;;;4119:185;;;4120:4;4119:185;;;;;;;;;;;;;;;;;;;-1:-1:-1;4342:18:5;;-1:-1:-1;4326:12:5;;:34;;;;;;;;;4318:87;;;;-1:-1:-1;;;4318:87:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4064:465;;;4470:39;;;;:48;4436:31;;;:82;4064:465;-1:-1:-1;4546:31:5;;;;2166:2418;-1:-1:-1;;;2166:2418:5:o;19008:1238::-;-1:-1:-1;;;;;774:24:5;;19176:4;774:24;;;:6;:24;;;;;;;;799:10;774:36;;;;;;;:43;;;19150:7;;774:43;;766:74;;;;;-1:-1:-1;;;766:74:5;;;;;;;;;;;;-1:-1:-1;;;766:74:5;;;;;;;;;;;;;;;19263:1:::1;19244:16;:20;19236:57;;;::::0;;-1:-1:-1;;;19236:57:5;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;19325:24:5;::::1;19304:18;19325:24:::0;;;:6:::1;:24;::::0;;;;;;;19350:10:::1;19325:36:::0;;;;;;;;19304:57;;::::1;::::0;::::1;::::0;;;;;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;::::1;::::0;;::::1;::::0;::::1;;;;::::0;;;;;19379:40;-1:-1:-1;19379:40:5::1;19371:85;;;::::0;;-1:-1:-1;;;19371:85:5;;::::1;;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;19467:17;19494:27:::0;19564:49:::1;19572:5;:22;;;19596:16;19564:7;:49::i;:::-;19531:82:::0;;-1:-1:-1;19531:82:5;-1:-1:-1;19642:18:5::1;19631:7;:29;;;;;;;;;19623:72;;;::::0;;-1:-1:-1;;;19623:72:5;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;19705:24:5;::::1;;::::0;;;:6:::1;:24;::::0;;;;;;;19730:10:::1;19705:36:::0;;;;;;:53:::1;;:75:::0;;;19972:20;::::1;::::0;19964:47:::1;::::0;19994:16;19964:7:::1;:47::i;:::-;19924:87:::0;;-1:-1:-1;19924:87:5;-1:-1:-1;20039:18:5::1;20028:7;:29;;;;;;;;;20021:37;;;;-1:-1:-1::0;;;;;20068:24:5;::::1;;::::0;;;:6:::1;:24;::::0;;;;;;;20093:10:::1;20068:36:::0;;;;;;;;;;:51;;::::1;:80:::0;;;20164:53;;;;;;;20093:10;;20068:24;20164:53:::1;::::0;;;;;;;;::::1;-1:-1:-1::0;20235:4:5::1;::::0;19008:1238;-1:-1:-1;;;;;;;19008:1238:5:o;705:42:7:-;743:4;705:42;:::o;10184:170:5:-;-1:-1:-1;;;;;10308:24:5;;;10282:7;10308:24;;;:6;:24;;;;;;;;:34;;;;;;;;;;;:39;;10184:170::o;11095:581::-;-1:-1:-1;;;;;11237:24:5;;;11200:4;11237:24;;;:6;:24;;;;;;;;:34;;;;;;;;;;;11216:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11200:4;;11216:55;;11285:32;;-1:-1:-1;11302:10:5;;:15;11285:32;11281:75;;;11340:5;11333:12;;;;;11281:75;11365:45;11413:51;11446:7;11455:8;11413:32;:51::i;:::-;11474:47;11524:10;;:49;;;-1:-1:-1;;;11524:49:5;;-1:-1:-1;;;;;11524:49:5;;;;;;;;;11365:99;;-1:-1:-1;11474:47:5;;11524:10;;;;;;:40;;:49;;;;;;;;;;;;;;:10;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11524:49:5;11590:79;;;;11095:581;-1:-1:-1;;;;;11095:581:5:o;14538:1190::-;-1:-1:-1;;;;;774:24:5;;14730:4;774:24;;;:6;:24;;;;;;;;799:10;774:36;;;;;;;:43;;;14683:7;;774:43;;766:74;;;;;-1:-1:-1;;;766:74:5;;;;;;;;;;;;-1:-1:-1;;;766:74:5;;;;;;;;;;;;;;;1817:10:21::1;::::0;::::1;;1809:41;;;::::0;;-1:-1:-1;;;1809:41:21;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1809:41:21;;;;;;;;;;;;;::::1;;1942:5;1929:18:::0;;-1:-1:-1;;1929:18:21::1;::::0;;14800:20:5;14792:60:::2;;;::::0;;-1:-1:-1;;;14792:60:5;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;14944:10;;;;;;;;;-1:-1:-1::0;;;;;14944:10:5::2;-1:-1:-1::0;;;;;14944:38:5::2;;14983:7;14944:47;;;;;;;;;;;;;-1:-1:-1::0;;;;;14944:47:5::2;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;14944:47:5;14936:94:::2;;;;-1:-1:-1::0;;;14936:94:5::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;15212:24:5;::::2;15080:17;15212:24:::0;;;:6:::2;:24;::::0;;;;;;;15237:10:::2;15212:36:::0;;;;;;;:51:::2;::::0;15080:17;;15191:112:::2;::::0;15277:16;15191:7:::2;:112::i;:::-;15151:152:::0;;-1:-1:-1;15151:152:5;-1:-1:-1;15332:18:5::2;15321:7;:29;;;;;;;;;15313:75;;;;-1:-1:-1::0;;;15313:75:5::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;15398:24:5;::::2;;::::0;;;:6:::2;:24;::::0;;;;;;;15423:10:::2;15398:36:::0;;;;;;;;;;:51;;::::2;:80:::0;;;15545:20;;-1:-1:-1;;;15545:20:5;;;;:82:::2;::::0;15603:4:::2;::::0;15610:16;;15398:24;;15545:18:::2;::::0;:20:::2;::::0;;::::2;::::0;15398:24;;15545:20;;;;;;15398:24;15545:20;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;15545:20:5;-1:-1:-1;;;;;15545:37:5::2;::::0;:82;;:37:::2;:82::i;:::-;15643:56;::::0;;;;;;;15670:10:::2;::::0;-1:-1:-1;;;;;15643:56:5;::::2;::::0;::::2;::::0;;;;::::2;::::0;;::::2;15717:4;15710:11;;;;-1:-1:-1::0;2126:10:21::1;:17:::0;;-1:-1:-1;;2126:17:21::1;2139:4;2126:17;::::0;;14538:1190:5;;-1:-1:-1;;14538:1190:5:o;11794:168::-;-1:-1:-1;;;;;11914:24:5;;;11891:4;11914:24;;;:6;:24;;;;;;;;:34;;;;;;;;;;;:41;;;;;;11794:168::o;21500:566::-;21645:4;21718:10;-1:-1:-1;;;;;21718:30:5;;;21710:76;;;;-1:-1:-1;;;21710:76:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;21859:24:5;;;21836:20;21859:24;;;:6;:24;;;;;;;;:34;;;;;;;;;;;;;:39;;21908:54;;;;21978:59;;;;;;;;;;;;;21859:39;;:34;:24;21978:59;;;;;;;;22055:4;22048:11;;;21500:566;;;;;;:::o;9553:491::-;-1:-1:-1;;;;;9805:24:5;;;9692:7;9805:24;;;:6;:24;;;;;;;;:34;;;;;;;;;;;;;;:39;;9858:49;;;;9921:51;;;;9986:41;;;;;9805:39;;9858:49;;9986:41;;;9553:491::o;1615:150:1:-;931:5;;-1:-1:-1;;;;;931:5:1;940:10;931:19;923:45;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;;;;1706:5:::1;::::0;1692:35:::1;::::0;1721:4:::1;::::0;-1:-1:-1;;;;;1706:5:1::1;::::0;1692:35:::1;::::0;1721:4;;1692:35:::1;1737:5;:21:::0;;-1:-1:-1;;;;;;1737:21:1::1;::::0;;1615:150::o;6594:2787:5:-;6793:7;6812:52;;:::i;:::-;-1:-1:-1;;;;;6984:24:5;;;;;;;:6;:24;;;;;;;;:34;;;;;;;;;:41;;;;;6976:72;;;;;-1:-1:-1;;;6976:72:5;;;;;;;;;;;;-1:-1:-1;;;6976:72:5;;;;;;;;;;;;;;;7104:21;7100:60;;7148:1;7141:8;;;;;7100:60;7184:1;7177:4;:8;7169:75;;;;-1:-1:-1;;;7169:75:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7316:33;7352:10;;;;;;;;;-1:-1:-1;;;;;7352:10:5;-1:-1:-1;;;;;7352:17:5;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7352:19:5;7436:20;;;-1:-1:-1;;;7436:20:5;;;;7352:19;;-1:-1:-1;;;;;;7412:23:5;;;;;;7436:18;;;;;;:20;;;;;7352:19;;7436:20;;;;;;;:18;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7436:20:5;:29;;;-1:-1:-1;;;7436:29:5;;;;-1:-1:-1;;;;;7436:27:5;;;;;;:29;;;;;;;;;;;;;;;:27;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7436:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;7436:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;7436:29:5;;;;;;-1:-1:-1;7436:29:5;;;;;;;;;;-1:-1:-1;7436:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7412:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7412:54:5;;7381:28;;;:85;;;;7593:20;;;-1:-1:-1;;;7593:20:5;;;;-1:-1:-1;;;;;7569:23:5;;;;;;7593:18;;;;;;:20;;;;;7412:54;7593:20;;;;;;:18;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7593:20:5;:29;;;-1:-1:-1;;;7593:29:5;;;;-1:-1:-1;;;;;7593:27:5;;;;;;:29;;;;;;;;;;;;;;;:27;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7593:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;7593:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;7593:29:5;;;;;;-1:-1:-1;7593:29:5;;;;;;;;;;-1:-1:-1;7593:29:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7569:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7569:54:5;7538:28;;;:85;7758:35;;;-1:-1:-1;;;7758:35:5;;;;-1:-1:-1;;;;;7758:33:5;;;;;:35;;;;;7569:54;;7758:35;;;;;;;:33;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7758:35:5;7725:30;;;:68;;;7841:1;7807:35;7803:366;;7906:57;7914:16;7932:4;:30;;;7906:7;:57::i;:::-;7873:29;;;7858:105;;;7859:4;7858:105;;;;;;;;;;;;;;;;;;;-1:-1:-1;8001:18:5;;-1:-1:-1;7985:12:5;;:34;;;;;;;;;7977:102;;;;-1:-1:-1;;;7977:102:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7803:366;;;8110:29;;;:48;;;7803:366;8304:48;;;;;;;;;8320:29;;;;8304:48;;8366:47;;;;;;;;8382:28;;;8366:47;;8284:139;;:6;:139::i;:::-;8251:29;;;8236:187;;;8237:4;8236:187;;;;;;;;;;;;;;;;;;;-1:-1:-1;8457:18:5;;-1:-1:-1;8441:12:5;;:34;;;;;;;;;8433:102;;;;-1:-1:-1;;;8433:102:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8633:114;8653:23;;;;;;;;8669:4;8653:23;;;8690:47;;;;;;;;8706:4;:28;;;8690:47;;;8633:6;:114::i;:::-;8612:17;;;8597:150;;;8598:4;8597:150;;;;;;;;;;;;;;;;;;;-1:-1:-1;8781:18:5;;-1:-1:-1;8765:12:5;;:34;;;;;;;;;8757:102;;;;-1:-1:-1;;;8757:102:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9106:90;9126:4;:29;;;9169:4;:17;;;9106:6;:90::i;:::-;9063:39;;;9048:148;;;9049:4;9048:148;;;;;;;;;;;;;;;;;;;-1:-1:-1;9230:18:5;;-1:-1:-1;9214:12:5;;:34;;;;;;;;;9206:102;;;;-1:-1:-1;;;9206:102:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9326:39:5;;;:48;;-1:-1:-1;6594:2787:5;;;;;;;:::o;4908:342::-;-1:-1:-1;;;;;5100:24:5;;;5056:7;5100:24;;;:6;:24;;;;;;;;:34;;;;;;;;;;;5079:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5056:7;;5151:92;;5115:7;;5125:8;;5151:37;:92::i;1969:230:1:-;931:5;;-1:-1:-1;;;;;931:5:1;940:10;931:19;923:45;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;;;;-1:-1:-1;;;;;2065:25:1;::::1;2057:64;;;::::0;;-1:-1:-1;;;2057:64:1;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;2150:5;::::0;2136:30:::1;::::0;-1:-1:-1;;;;;2136:30:1;;::::1;::::0;2150:5:::1;::::0;2136:30:::1;::::0;2150:5:::1;::::0;2136:30:::1;2176:5;:16:::0;;-1:-1:-1;;;;;;2176:16:1::1;-1:-1:-1::0;;;;;2176:16:1;;;::::1;::::0;;;::::1;::::0;;1969:230::o;425:37:7:-;;;;;;-1:-1:-1;;;;;425:37:7;;:::o;182:20:3:-;;;-1:-1:-1;;;;;182:20:3;;:::o;2701:239:8:-;2763:9;2774:7;2802:1;2797;:6;2793:141;;-1:-1:-1;2827:18:8;;-1:-1:-1;2847:5:8;;;2819:34;;2793:141;-1:-1:-1;2892:27:8;;-1:-1:-1;2921:1:8;2793:141;2701:239;;;;;:::o;857:214:22:-;1004:59;;;-1:-1:-1;;;;;1004:59:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1004:59:22;-1:-1:-1;;;1004:59:22;;;978:86;;997:5;;978:18;:86::i;:::-;857:214;;;:::o;587:262:8:-;649:9;;691:5;;;711:6;;;707:136;;741:18;;-1:-1:-1;761:1:8;-1:-1:-1;733:30:8;;707:136;802:26;830:1;794:38;;;;;;;3089:308:13;3201:9;3212:10;;:::i;:::-;3235:13;3250;3267:12;3274:1;3277;3267:6;:12::i;:::-;3234:45;;-1:-1:-1;3234:45:13;-1:-1:-1;3300:18:13;3293:3;:25;;;;;;;;;3289:72;;3342:3;;-1:-1:-1;3347:2:13;-1:-1:-1;3334:16:13;;3289:72;3377:13;3384:2;3388:1;3377:6;:13::i;:::-;3370:20;;;;;;3089:308;;;;;;;:::o;1218:533::-;1285:9;1296:10;;:::i;:::-;1319:14;1335:23;1362:29;1370:1;:10;;;408:4:14;1362:7:13;:29::i;:::-;1318:73;;-1:-1:-1;1318:73:13;-1:-1:-1;1413:18:13;1405:4;:26;;;;;;;;;1401:92;;-1:-1:-1;1461:20:13;;;;;;;;;-1:-1:-1;1461:20:13;;1455:4;;-1:-1:-1;1461:20:13;-1:-1:-1;1447:35:13;;1401:92;1504:14;1520:16;1540:36;1548:15;1565:1;:10;;;1540:7;:36::i;:::-;1503:73;;-1:-1:-1;1503:73:13;-1:-1:-1;1598:18:13;1590:4;:26;;;;;;;;;1586:92;;1640:4;1646:20;;;;;;;;1662:1;1646:20;;;1632:35;;;;;;;;;;1586:92;1716:27;;;;;;;;;;;;-1:-1:-1;;1716:27:13;;-1:-1:-1;1218:533:13;-1:-1:-1;;;;;;1218:533:13:o;1328:218:8:-;1390:9;;1424:6;1420:75;;-1:-1:-1;1454:26:8;;-1:-1:-1;1482:1:8;1446:38;;1420:75;1513:18;1537:1;1533;:5;;;;;;1505:34;;;;1328:218;;;;;:::o;1077:250:22:-;1250:69;;;-1:-1:-1;;;;;1250:69:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1250:69:22;-1:-1:-1;;;1250:69:22;;;1224:96;;1243:5;;1224:18;:96::i;:::-;1077:250;;;;:::o;2223:343:8:-;2285:9;;2319:6;2315:67;;-1:-1:-1;2349:18:8;;-1:-1:-1;2349:18:8;2341:30;;2315:67;2404:5;;;2408:1;2404;:5;:1;2424:5;;;;;:10;2420:140;;2458:26;2486:1;2450:38;;;;;;;2420:140;2527:18;;-1:-1:-1;2547:1:8;-1:-1:-1;2519:30:8;;1843:1152:13;1910:9;1921:10;;:::i;:::-;1944:14;1960:27;1991:31;1999:1;:10;;;2011:1;:10;;;1991:7;:31::i;:::-;1943:79;;-1:-1:-1;1943:79:13;-1:-1:-1;2044:18:13;2036:4;:26;;;;;;;;;2032:92;;-1:-1:-1;2092:20:13;;;;;;;;;-1:-1:-1;2092:20:13;;2086:4;;-1:-1:-1;2092:20:13;-1:-1:-1;2078:35:13;;2032:92;2458:14;;2518:42;459:12:14;2540:19:13;2518:7;:42::i;:::-;2457:103;;-1:-1:-1;2457:103:13;-1:-1:-1;2582:18:13;2574:4;:26;;;;;;;;;2570:92;;2624:4;2630:20;;;;;;;;2646:1;2630:20;;;2616:35;;;;;;;;;;2570:92;2673:14;2689:15;2708:51;2716:32;408:4:14;2708:7:13;:51::i;:::-;2672:87;;-1:-1:-1;2672:87:13;-1:-1:-1;2903:18:13;2895:4;:26;;;;;;;;;2888:34;;;;2961:26;;;;;;;;;;;;-1:-1:-1;;2961:26:13;;-1:-1:-1;1843:1152:13;-1:-1:-1;;;;;;;;1843:1152:13:o;1750:702:22:-;2175:23;2201:67;2222:5;2230:4;2201:67;;;;;;;;;;;;;;;;;:12;:67::i;:::-;2282:17;;2175:93;;-1:-1:-1;2282:21:22;2278:168;;2381:10;2370:30;;;;;;;;;;;;;;;-1:-1:-1;2370:30:22;2362:73;;;;;-1:-1:-1;;;2362:73:22;;;;;;;;;;;;;;;;;;;;;;;;;;;2458:961;2590:12;2622:19;:6;-1:-1:-1;;;;;2622:17:22;;:19::i;:::-;2614:67;;;;-1:-1:-1;;;2614:67:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2755:12;2769:23;2796:6;-1:-1:-1;;;;;2796:11:22;2808:4;2796:17;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2796:17:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2754:59;;;;2827:7;2823:590;;;2857:10;-1:-1:-1;2850:17:22;;-1:-1:-1;2850:17:22;2823:590;2971:17;;:21;2967:436;;3236:10;3230:17;3296:15;3283:10;3279:2;3275:19;3268:44;3185:145;3375:12;3368:20;;-1:-1:-1;;;3368:20:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;911:634:0;971:4;1448:20;;1278:66;1495:23;;;;;;:42;;-1:-1:-1;;1522:15:0;;;1487:51;-1:-1:-1;;911:634:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://928357a59c778e5f8d069b600a19b817e5393c5184a7792ffe7f0903b50afcd0
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $102,140 | 0.00166965 | $170.54 |
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.