Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 9 from a total of 9 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer | 14661338 | 1000 days ago | IN | 0 ETH | 0.00159333 | ||||
Transfer | 14661330 | 1000 days ago | IN | 0 ETH | 0.0016659 | ||||
Approve | 14655111 | 1001 days ago | IN | 0 ETH | 0.00158956 | ||||
Approve | 14655097 | 1001 days ago | IN | 0 ETH | 0.00316573 | ||||
Approve | 11927412 | 1425 days ago | IN | 0 ETH | 0.01090208 | ||||
Approve | 11884628 | 1431 days ago | IN | 0 ETH | 0.00886691 | ||||
Approve | 11875427 | 1433 days ago | IN | 0 ETH | 0.00452778 | ||||
_transfer Admin | 11873584 | 1433 days ago | IN | 0 ETH | 0.002775 | ||||
_set Non Recover... | 11873531 | 1433 days ago | IN | 0 ETH | 0.0025868 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
11870482 | 1434 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
FyToken
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 "./CarefulMath.sol"; import "./Erc20.sol"; import "./Erc20Interface.sol"; import "./Erc20Permit.sol"; import "./Erc20Recover.sol"; import "./ReentrancyGuard.sol"; import "./BalanceSheetInterface.sol"; import "./FintrollerInterface.sol"; import "./FyTokenInterface.sol"; import "./RedemptionPool.sol"; /** * @title FyToken * @author Hifi * @notice Zero-coupon bond that tracks an Erc20 underlying asset. */ contract FyToken is ReentrancyGuard, /* no depedency */ FyTokenInterface, /* one dependency */ Admin, /* two dependencies */ Exponential, /* two dependencies */ Erc20, /* three dependencies */ Erc20Permit, /* five dependencies */ Erc20Recover /* five dependencies */ { modifier isVaultOpen(address account) { require(balanceSheet.isVaultOpen(this, account), "ERR_VAULT_NOT_OPEN"); _; } /** * @notice The fyToken always has 18 decimals. * @dev Instantiates the Redemption Pool. * @param name_ Erc20 name of this token. * @param symbol_ Erc20 symbol of this token. * @param expirationTime_ Unix timestamp in seconds for when this token expires. * @param fintroller_ The address of the Fintroller contract. * @param balanceSheet_ The address of the BalanceSheet contract. * @param underlying_ The contract address of the underlying asset. * @param collateral_ The contract address of the collateral asset. */ constructor( string memory name_, string memory symbol_, uint256 expirationTime_, FintrollerInterface fintroller_, BalanceSheetInterface balanceSheet_, Erc20Interface underlying_, Erc20Interface collateral_ ) Erc20Permit(name_, symbol_, 18) Admin() { uint8 defaultNumberOfDecimals = 18; /* Set the underlying contract and calculate the decimal scalar offsets. */ uint256 underlyingDecimals = underlying_.decimals(); require(underlyingDecimals > 0, "ERR_FYTOKEN_CONSTRUCTOR_UNDERLYING_DECIMALS_ZERO"); require(underlyingDecimals <= defaultNumberOfDecimals, "ERR_FYTOKEN_CONSTRUCTOR_UNDERLYING_DECIMALS_OVERFLOW"); underlyingPrecisionScalar = 10**(defaultNumberOfDecimals - underlyingDecimals); underlying = underlying_; /* Set the collateral contract and calculate the decimal scalar offsets. */ uint256 collateralDecimals = collateral_.decimals(); require(collateralDecimals > 0, "ERR_FYTOKEN_CONSTRUCTOR_COLLATERAL_DECIMALS_ZERO"); require(defaultNumberOfDecimals >= collateralDecimals, "ERR_FYTOKEN_CONSTRUCTOR_COLLATERAL_DECIMALS_OVERFLOW"); collateralPrecisionScalar = 10**(defaultNumberOfDecimals - collateralDecimals); collateral = collateral_; /* Set the unix expiration time. */ require(expirationTime_ > block.timestamp, "ERR_FYTOKEN_CONSTRUCTOR_EXPIRATION_TIME_NOT_VALID"); expirationTime = expirationTime_; /* Set the Fintroller contract and sanity check it. */ fintroller = fintroller_; fintroller.isFintroller(); /* Set the Balance Sheet contract and sanity check it. */ balanceSheet = balanceSheet_; balanceSheet.isBalanceSheet(); /* Create the Redemption Pool contract and transfer the owner from the fyToken itself to the current caller. */ redemptionPool = new RedemptionPool(fintroller_, this); AdminInterface(address(redemptionPool))._transferAdmin(msg.sender); } /** * CONSTANT FUNCTIONS */ /** * @notice Checks if the bond matured. * @return bool true = bond matured, otherwise it didn't. */ function isMatured() public view override returns (bool) { return block.timestamp >= expirationTime; } /** * NON-CONSTANT FUNCTIONS */ struct BorrowLocalVars { MathError mathErr; uint256 debt; uint256 debtCeiling; uint256 lockedCollateral; uint256 hypotheticalCollateralizationRatioMantissa; uint256 hypotheticalTotalSupply; uint256 newDebt; uint256 thresholdCollateralizationRatioMantissa; } /** * @notice Increases the debt of the caller and mints new fyToken. * * @dev Emits a {Borrow}, {Mint} and {Transfer} event. * * Requirements: * * - The vault must be open. * - Must be called prior to maturation. * - The amount to borrow cannot be zero. * - The Fintroller must allow this action to be performed. * - The locked collateral cannot be zero. * - The total supply of fyTokens cannot exceed the debt ceiling. * - The caller must not fall below the threshold collateralization ratio. * * @param borrowAmount The amount of fyTokens to borrow and print into existence. * @return bool true = success, otherwise it reverts. */ function borrow(uint256 borrowAmount) public override isVaultOpen(msg.sender) nonReentrant returns (bool) { BorrowLocalVars memory vars; /* Checks: bond not matured. */ require(isMatured() == false, "ERR_BOND_MATURED"); /* Checks: the zero edge case. */ require(borrowAmount > 0, "ERR_BORROW_ZERO"); /* Checks: the Fintroller allows this action to be performed. */ require(fintroller.getBorrowAllowed(this), "ERR_BORROW_NOT_ALLOWED"); /* Checks: debt ceiling. */ (vars.mathErr, vars.hypotheticalTotalSupply) = addUInt(totalSupply, borrowAmount); require(vars.mathErr == MathError.NO_ERROR, "ERR_BORROW_MATH_ERROR"); vars.debtCeiling = fintroller.getBondDebtCeiling(this); require(vars.hypotheticalTotalSupply <= vars.debtCeiling, "ERR_BORROW_DEBT_CEILING_OVERFLOW"); /* Add the borrow amount to the borrower account's current debt. */ (vars.debt, , vars.lockedCollateral, ) = balanceSheet.getVault(this, msg.sender); require(vars.lockedCollateral > 0, "ERR_BORROW_LOCKED_COLLATERAL_ZERO"); (vars.mathErr, vars.newDebt) = addUInt(vars.debt, borrowAmount); require(vars.mathErr == MathError.NO_ERROR, "ERR_BORROW_MATH_ERROR"); /* Checks: the hypothetical collateralization ratio is above the threshold. */ vars.hypotheticalCollateralizationRatioMantissa = balanceSheet.getHypotheticalCollateralizationRatio( this, msg.sender, vars.lockedCollateral, vars.newDebt ); vars.thresholdCollateralizationRatioMantissa = fintroller.getBondCollateralizationRatio(this); require( vars.hypotheticalCollateralizationRatioMantissa >= vars.thresholdCollateralizationRatioMantissa, "ERR_BELOW_COLLATERALIZATION_RATIO" ); /* Effects: print the new fyTokens into existence. */ mintInternal(msg.sender, borrowAmount); /* Emit a Transfer event. */ emit Transfer(address(this), msg.sender, borrowAmount); /* Interactions: increase the debt of the borrower account. */ require(balanceSheet.setVaultDebt(this, msg.sender, vars.newDebt), "ERR_BORROW_CALL_SET_VAULT_DEBT"); /* Emit a Borrow event. */ emit Borrow(msg.sender, borrowAmount); return true; } /** * @notice Destroys `burnAmount` tokens from `holder`, reducing the token supply. * * @dev Emits a {Burn} and a {Transfer} event. * * Requirements: * * - Must be called prior to maturation. * - Can only be called by the Redemption Pool. * - The amount to burn cannot be zero. * * @param holder The account whose fyTokens to burn. * @param burnAmount The amount of fyTokens to burn. * @return bool true = success, otherwise it reverts. */ function burn(address holder, uint256 burnAmount) external override nonReentrant returns (bool) { /* Checks: the caller is the Redemption Pool. */ require(msg.sender == address(redemptionPool), "ERR_BURN_NOT_AUTHORIZED"); /* Checks: the zero edge case. */ require(burnAmount > 0, "ERR_BURN_ZERO"); /* Effects: burns the fyTokens. */ burnInternal(holder, burnAmount); /* Emit a Transfer event. */ emit Transfer(holder, address(this), burnAmount); return true; } struct LiquidateBorrowsLocalVars { MathError mathErr; uint256 collateralizationRatioMantissa; uint256 lockedCollateral; bool isAccountUnderwater; } /** * @notice Repays the debt of the borrower and rewards the caler with a surplus of collateral. * * @dev Emits a {RepayBorrow}, {Transfer}, {ClutchCollateral} and {LiquidateBorrow} event. * * Requirements: * * - The vault must be open. * - The liquidator cannot liquidate themselves. * - The amount to repay cannot be zero. * - The Fintroller must allow this action to be performed. * - The borrower must be underwater if the bond didn't mature. * - The caller must have at least `repayAmount` fyTokens. * - The borrower must have at least `repayAmount` debt. * - The amount of clutched collateral cannot be more than what the borrower has in the vault. * * @param borrower The account to liquidate. * @param repayAmount The amount of fyTokens to repay. * @return bool true = success, otherwise it reverts. */ function liquidateBorrow(address borrower, uint256 repayAmount) external override isVaultOpen(borrower) nonReentrant returns (bool) { LiquidateBorrowsLocalVars memory vars; /* Checks: borrowers cannot self liquidate. */ require(msg.sender != borrower, "ERR_LIQUIDATE_BORROW_SELF"); /* Checks: the zero edge case. */ require(repayAmount > 0, "ERR_LIQUIDATE_BORROW_ZERO"); /* Checks: the Fintroller allows this action to be performed. */ require(fintroller.getLiquidateBorrowAllowed(this), "ERR_LIQUIDATE_BORROW_NOT_ALLOWED"); /* After maturation, any vault can be liquidated, irrespective of collateralization ratio. */ if (isMatured() == false) { /* Checks: the borrower fell below the threshold collateralization ratio. */ vars.isAccountUnderwater = balanceSheet.isAccountUnderwater(this, borrower); require(vars.isAccountUnderwater, "ERR_ACCOUNT_NOT_UNDERWATER"); } /* Effects & Interactions: repay the borrower's debt. */ repayBorrowInternal(msg.sender, borrower, repayAmount); /* Interactions: clutch the collateral. */ uint256 clutchableCollateralAmount = balanceSheet.getClutchableCollateral(this, repayAmount); require( balanceSheet.clutchCollateral(this, msg.sender, borrower, clutchableCollateralAmount), "ERR_LIQUIDATE_BORROW_CALL_CLUTCH_COLLATERAL" ); emit LiquidateBorrow(msg.sender, borrower, repayAmount, clutchableCollateralAmount); return true; } /** /** @notice Prints new tokens into existence and assigns them to `beneficiary`, * increasing the total supply. * * @dev Emits a {Mint} and a {Transfer} event. * * Requirements: * * - Can only be called by the Redemption Pool. * - The amount to mint cannot be zero. * * @param beneficiary The borrower account for which to mint the tokens. * @param mintAmount The amount of fyTokens to print into existence. * @return bool true = success, otherwise it reverts. */ function mint(address beneficiary, uint256 mintAmount) external override nonReentrant returns (bool) { /* Checks: the caller is the Redemption Pool. */ require(msg.sender == address(redemptionPool), "ERR_MINT_NOT_AUTHORIZED"); /* Checks: the zero edge case. */ require(mintAmount > 0, "ERR_MINT_ZERO"); /* Effects: print the new fyTokens into existence. */ mintInternal(beneficiary, mintAmount); /* Emit a Transfer event. */ emit Transfer(address(this), beneficiary, mintAmount); return true; } /** * @notice Deletes the borrower account's debt from the registry and take the fyTokens * out of circulation. * * @dev Emits a {Burn}, {Transfer} and {RepayBorrow} event. * * Requirements: * * - The vault must be open. * - The amount to repay cannot be zero. * - The Fintroller must allow this action to be performed. * - The caller must have at least `repayAmount` fyTokens. * - The caller must have at least `repayAmount` debt. * * @param repayAmount The amount of fyTokens to repay. * @return bool true = success, otherwise it reverts. */ function repayBorrow(uint256 repayAmount) external override isVaultOpen(msg.sender) nonReentrant returns (bool) { repayBorrowInternal(msg.sender, msg.sender, repayAmount); return true; } /** * @notice Clears the borrower account's debt from the registry and take the fyTokens * out of circulation. * * @dev Emits a {Burn}, {Transfer} and {RepayBorrow} event. * * Requirements: same as the `repayBorrow` function, but here `borrower` is the account that must * have at least `repayAmount` fyTokens to repay the borrow. * * @param borrower The borrower account for which to repay the borrow. * @param repayAmount The amount of fyTokens to repay. * @return bool true = success, otherwise it reverts. */ function repayBorrowBehalf(address borrower, uint256 repayAmount) external override isVaultOpen(borrower) nonReentrant returns (bool) { repayBorrowInternal(msg.sender, borrower, repayAmount); return true; } /** * @notice Updates the Fintroller contract's address saved in storage. * * @dev Throws a {SetFintroller} event. * * Requirements: * * - The caller must be the admin. * - The new Fintroller must pass the inspection. * * @param newFintroller The address of the new Fintroller contract. * @return bool true = success, otherwise it reverts. */ function _setFintroller(FintrollerInterface newFintroller) external override onlyAdmin returns (bool) { /* Checks: sanity check the new Fintroller contract. */ require(newFintroller.isFintroller(), "ERR_SET_FINTROLLER_INSPECTION"); /* Effects: update storage. */ FintrollerInterface oldFintroller = fintroller; fintroller = newFintroller; emit SetFintroller(admin, oldFintroller, newFintroller); return true; } /** * INTERNAL FUNCTIONS */ /** * @dev See the documentation for the public functions that call this internal function. */ function repayBorrowInternal( address payer, address borrower, uint256 repayAmount ) internal { /* Checks: the zero edge case. */ require(repayAmount > 0, "ERR_REPAY_BORROW_ZERO"); /* Checks: the Fintroller allows this action to be performed. */ require(fintroller.getRepayBorrowAllowed(this), "ERR_REPAY_BORROW_NOT_ALLOWED"); /* Checks: borrower has a debt to pay. */ uint256 debt = balanceSheet.getVaultDebt(this, borrower); require(debt >= repayAmount, "ERR_REPAY_BORROW_INSUFFICIENT_DEBT"); /* Checks: the payer has enough fyTokens. */ require(balanceOf(payer) >= repayAmount, "ERR_REPAY_BORROW_INSUFFICIENT_BALANCE"); /* Effects: burn the fyTokens. */ burnInternal(payer, repayAmount); /* Emit a Transfer event. */ emit Transfer(payer, address(this), repayAmount); /* Calculate the new debt of the borrower. */ MathError mathErr; uint256 newDebt; (mathErr, newDebt) = subUInt(debt, repayAmount); /* This operation can't fail because of the previous `require`. */ assert(mathErr == MathError.NO_ERROR); /* Interactions: reduce the debt of the borrower . */ require(balanceSheet.setVaultDebt(this, borrower, newDebt), "ERR_REPAY_BORROW_CALL_SET_VAULT_DEBT"); /* Emit both a RepayBorrow event. */ emit RepayBorrow(payer, borrower, repayAmount, newDebt); } }
/* 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 "./Erc20Interface.sol"; import "./CarefulMath.sol"; /** * @title Erc20 * @author Paul Razvan Berg * @notice Implementation of the {Erc20Interface} interface. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of Erc20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the Erc may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {Erc20Interface-approve}. * * @dev Forked from OpenZeppelin * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.2.0/contracts/token/Erc20/Erc20.sol */ contract Erc20 is CarefulMath, /* no dependency */ Erc20Interface /* one dependency */ { /** * @notice All three of these values are immutable: they can only be set once during construction. * @param name_ Erc20 name of this token. * @param symbol_ Erc20 symbol of this token. * @param decimals_ Erc20 decimal precision of this token. */ constructor( string memory name_, string memory symbol_, uint8 decimals_ ) { name = name_; symbol = symbol_; decimals = decimals_; } /** * CONSTANT FUNCTIONS */ /** * @notice Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view virtual override returns (uint256) { return allowances[owner][spender]; } /** * @notice Returns the amount of tokens owned by `account`. */ function balanceOf(address account) public view virtual override returns (uint256) { return balances[account]; } /** * NON-CONSTANT FUNCTIONS */ /** * @notice Sets `amount` as the allowance of `spender` over the caller's tokens. * * @dev IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. * * @return a boolean value indicating whether the operation succeeded. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) external virtual override returns (bool) { approveInternal(msg.sender, spender, amount); return true; } /** * @notice Atomically decreases the allowance granted to `spender` by the caller. * * @dev This is an alternative to {approve} that can be used as a mitigation for * problems described in {Erc20Interface-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool) { MathError mathErr; uint256 newAllowance; (mathErr, newAllowance) = subUInt(allowances[msg.sender][spender], subtractedValue); require(mathErr == MathError.NO_ERROR, "ERR_ERC20_DECREASE_ALLOWANCE_UNDERFLOW"); approveInternal(msg.sender, spender, newAllowance); return true; } /** * @notice Atomically increases the allowance granted to `spender` by the caller. * * @dev This is an alternative to {approve} that can be used as a mitigation for * problems described above. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool) { MathError mathErr; uint256 newAllowance; (mathErr, newAllowance) = addUInt(allowances[msg.sender][spender], addedValue); require(mathErr == MathError.NO_ERROR, "ERR_ERC20_INCREASE_ALLOWANCE_OVERFLOW"); approveInternal(msg.sender, spender, newAllowance); return true; } /** * @notice Moves `amount` tokens from the caller's account to `recipient`. * * @dev Emits a {Transfer} event. * * @return a boolean value indicating whether the operation succeeded. * * Requirements: * * - `recipient` cannot be the zero address. * - The caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) external virtual override returns (bool) { transferInternal(msg.sender, recipient, amount); return true; } /** * @notice See Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * @dev Emits a {Transfer} event. Emits an {Approval} event indicating the * updated allowance. This is not required by the Erc. See the note at the * beginning of {Erc20}; * * @return a boolean value indicating whether the operation succeeded. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - The caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) external virtual override returns (bool) { transferInternal(sender, recipient, amount); MathError mathErr; uint256 newAllowance; (mathErr, newAllowance) = subUInt(allowances[sender][msg.sender], amount); require(mathErr == MathError.NO_ERROR, "ERR_ERC20_TRANSFER_FROM_INSUFFICIENT_ALLOWANCE"); approveInternal(sender, msg.sender, newAllowance); return true; } /** * INTERNAL FUNCTIONS */ /** * @notice Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * @dev This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function approveInternal( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0x00), "ERR_ERC20_APPROVE_FROM_ZERO_ADDRESS"); require(spender != address(0x00), "ERR_ERC20_APPROVE_TO_ZERO_ADDRESS"); allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @notice Destroys `burnAmount` tokens from `holder`, recuding the token supply. * * @dev Emits a {Burn} event. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `holder` must have at least `amount` tokens. */ function burnInternal(address holder, uint256 burnAmount) internal { MathError mathErr; uint256 newHolderBalance; uint256 newTotalSupply; /* Burn the yTokens. */ (mathErr, newHolderBalance) = subUInt(balances[holder], burnAmount); require(mathErr == MathError.NO_ERROR, "ERR_ERC20_BURN_BALANCE_UNDERFLOW"); balances[holder] = newHolderBalance; /* Reduce the total supply. */ (mathErr, newTotalSupply) = subUInt(totalSupply, burnAmount); require(mathErr == MathError.NO_ERROR, "ERR_ERC20_BURN_TOTAL_SUPPLY_UNDERFLOW"); totalSupply = newTotalSupply; emit Burn(holder, burnAmount); } /** @notice Prints new tokens into existence and assigns them to `beneficiary`, * increasing the total supply. * * @dev Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - The beneficiary's balance and the total supply cannot overflow. */ function mintInternal(address beneficiary, uint256 mintAmount) internal { MathError mathErr; uint256 newBeneficiaryBalance; uint256 newTotalSupply; /* Mint the yTokens. */ (mathErr, newBeneficiaryBalance) = addUInt(balances[beneficiary], mintAmount); require(mathErr == MathError.NO_ERROR, "ERR_ERC20_MINT_BALANCE_OVERFLOW"); balances[beneficiary] = newBeneficiaryBalance; /* Increase the total supply. */ (mathErr, newTotalSupply) = addUInt(totalSupply, mintAmount); require(mathErr == MathError.NO_ERROR, "ERR_ERC20_MINT_TOTAL_SUPPLY_OVERFLOW"); totalSupply = newTotalSupply; emit Mint(beneficiary, mintAmount); } /** * @notice Moves `amount` tokens from `sender` to `recipient`. * * @dev This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function transferInternal( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0x00), "ERR_ERC20_TRANSFER_FROM_ZERO_ADDRESS"); require(recipient != address(0x00), "ERR_ERC20_TRANSFER_TO_ZERO_ADDRESS"); MathError mathErr; uint256 newSenderBalance; uint256 newRecipientBalance; (mathErr, newSenderBalance) = subUInt(balances[sender], amount); require(mathErr == MathError.NO_ERROR, "ERR_ERC20_TRANSFER_SENDER_BALANCE_UNDERFLOW"); balances[sender] = newSenderBalance; (mathErr, newRecipientBalance) = addUInt(balances[recipient], amount); assert(mathErr == MathError.NO_ERROR); balances[recipient] = newRecipientBalance; emit Transfer(sender, recipient, amount); } }
/* 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; import "./Erc20.sol"; import "./Erc20PermitInterface.sol"; /** * @title Erc20Permit * @author Paul Razvan Berg * @notice Extension of Erc20 that allows token holders to use their tokens * without sending any transactions by setting the allowance with a signature * using the `permit` method, and then spend them via `transferFrom`. * @dev See https://eips.ethereum.org/EIPS/eip-2612. */ contract Erc20Permit is Erc20PermitInterface, /* one dependency */ Erc20 /* three dependencies */ { constructor( string memory name_, string memory symbol_, uint8 decimals_ ) Erc20(name_, symbol_, decimals_) { uint256 chainId; /* solhint-disable-next-line no-inline-assembly */ assembly { chainId := chainid() } DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256(bytes(version)), chainId, address(this) ) ); } /** * @dev Sets `amount` as the allowance of `spender` over `owner`'s tokens, * assuming the latter's signed approval. * * IMPORTANT: The same issues Erc20 `approve` has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the Eip712-formatted function arguments. * - The signature must use `owner`'s current nonce. */ function permit( address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external override { require(owner != address(0x00), "ERR_ERC20_PERMIT_OWNER_ZERO_ADDRESS"); require(spender != address(0x00), "ERR_ERC20_PERMIT_SPENDER_ZERO_ADDRESS"); require(deadline >= block.timestamp, "ERR_ERC20_PERMIT_EXPIRED"); /* It's safe to use the "+" operator here because the nonce cannot realistically overflow, ever. */ bytes32 hashStruct = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, nonces[owner]++, deadline)); bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, hashStruct)); address recoveredOwner = ecrecover(digest, v, r, s); require(recoveredOwner != address(0x00), "ERR_ERC20_PERMIT_RECOVERED_OWNER_ZERO_ADDRESS"); require(recoveredOwner == owner, "ERR_ERC20_PERMIT_INVALID_SIGNATURE"); approveInternal(owner, spender, amount); } }
/* SPDX-License-Identifier: MIT */ /* solhint-disable var-name-mixedcase */ pragma solidity ^0.7.0; import "./Erc20PermitStorage.sol"; /** * @notice Erc20PermitInterface * @author Paul Razvan Berg */ abstract contract Erc20PermitInterface is Erc20PermitStorage { /** * NON-CONSTANT FUNCTIONS */ function permit( address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external virtual; }
/* SPDX-License-Identifier: MIT */ /* solhint-disable var-name-mixedcase */ pragma solidity ^0.7.0; /** * @notice Erc20PermitStorage * @author Paul Razvan Berg */ abstract contract Erc20PermitStorage { /** * @notice The Eip712 domain's keccak256 hash. */ bytes32 public DOMAIN_SEPARATOR; /** * @notice keccak256("Permit(address owner,address spender,uint256 amount,uint256 nonce,uint256 deadline)"); */ bytes32 public constant PERMIT_TYPEHASH = 0xfc77c2b9d30fe91687fd39abb7d16fcdfe1472d065740051ab8b13e4bf4a617f; /** * @notice Provides replay protection. */ mapping(address => uint256) public nonces; /** * @notice Eip712 version of this implementation. */ string public constant version = "1"; }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; import "./Admin.sol"; import "./Erc20Interface.sol"; import "./Erc20RecoverInterface.sol"; import "./SafeErc20.sol"; /** * @title Erc20Recover * @author Paul Razvan Berg * @notice Gives the administrator the ability to recover the Erc20 tokens that * had been sent (accidentally, or not) to the contract. */ abstract contract Erc20Recover is Erc20RecoverInterface, /* one dependency */ Admin /* two dependencies */ { using SafeErc20 for Erc20Interface; /** * @notice Sets the tokens that this contract cannot recover. * * @dev Emits a {SetNonRecoverableTokens} event. * * Requirements: * * - The caller must be the administrator. * - The contract must be non-initialized. * - The array of given tokens cannot be empty. * * @param tokens The array of tokens to set as non-recoverable. */ function _setNonRecoverableTokens(Erc20Interface[] calldata tokens) external override onlyAdmin { /* Checks */ require(isRecoverInitialized == false, "ERR_INITALIZED"); /* Iterate over the token list, sanity check each and update the mapping. */ uint256 length = tokens.length; for (uint256 i = 0; i < length; i += 1) { tokens[i].symbol(); nonRecoverableTokens.push(tokens[i]); } /* Effects: prevent this function from ever being called again. */ isRecoverInitialized = true; emit SetNonRecoverableTokens(admin, tokens); } /** * @notice Recover Erc20 tokens sent to this contract (by accident or otherwise). * @dev Emits a {RecoverToken} event. * * Requirements: * * - The caller must be the administrator. * - The contract must be initialized. * - The amount to recover cannot be zero. * - The token to recover cannot be among the non-recoverable tokens. * * @param token The token to make the recover for. * @param recoverAmount The uint256 amount to recover, specified in the token's decimal system. */ function _recover(Erc20Interface token, uint256 recoverAmount) external override onlyAdmin { /* Checks */ require(isRecoverInitialized == true, "ERR_NOT_INITALIZED"); require(recoverAmount > 0, "ERR_RECOVER_ZERO"); bytes32 tokenSymbolHash = keccak256(bytes(token.symbol())); uint256 length = nonRecoverableTokens.length; /** * We iterate over the non-recoverable token array and check that: * * 1. The addresses of the tokens are not the same * 2. The symbols of the tokens are not the same * * It is true that the second check may lead to a false positive, but * there is no better way to fend off against proxied tokens. */ for (uint256 i = 0; i < length; i += 1) { require( address(token) != address(nonRecoverableTokens[i]) && tokenSymbolHash != keccak256(bytes(nonRecoverableTokens[i].symbol())), "ERR_RECOVER_NON_RECOVERABLE_TOKEN" ); } /* Interactions */ token.safeTransfer(admin, recoverAmount); emit Recover(admin, token, recoverAmount); } }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; import "./Erc20Interface.sol"; import "./Erc20RecoverStorage.sol"; abstract contract Erc20RecoverInterface is Erc20RecoverStorage { /** * NON-CONSTANT FUNCTIONS */ function _recover(Erc20Interface token, uint256 recoverAmount) external virtual; function _setNonRecoverableTokens(Erc20Interface[] calldata tokens) external virtual; /** * EVENTS */ event Recover(address indexed admin, Erc20Interface token, uint256 recoverAmount); event SetNonRecoverableTokens(address indexed admin, Erc20Interface[] nonRecoverableTokens); }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.0; import "./Erc20Interface.sol"; abstract contract Erc20RecoverStorage { /** * @notice The tokens that can be recovered cannot be in this mapping. */ Erc20Interface[] public nonRecoverableTokens; /** * @dev A flag that signals whether the the non-recoverable tokens were set or not. */ bool internal isRecoverInitialized; }
/* 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 "./Admin.sol"; import "./CarefulMath.sol"; import "./Erc20Interface.sol"; import "./Erc20Recover.sol"; import "./SafeErc20.sol"; import "./ReentrancyGuard.sol"; import "./FintrollerInterface.sol"; import "./RedemptionPoolInterface.sol"; /** * @title RedemptionPool * @author Hifi * @notice Mints 1 fyToken in exhchange for 1 underlying before maturation and burns 1 fyToken * in exchange for 1 underlying after maturation. * @dev Instantiated by the fyToken in its constructor. */ contract RedemptionPool is CarefulMath, /* no dependency */ ReentrancyGuard, /* no dependency */ RedemptionPoolInterface, /* one dependency */ Admin, /* two dependencies */ Erc20Recover /* five dependencies */ { using SafeErc20 for Erc20Interface; /** * @param fintroller_ The address of the Fintroller contract. * @param fyToken_ The address of the fyToken contract. */ constructor(FintrollerInterface fintroller_, FyTokenInterface fyToken_) Admin() { /* Set the Fintroller contract and sanity check it. */ fintroller = fintroller_; fintroller.isFintroller(); /** * Set the fyToken contract. It cannot be sanity-checked because the fyToken creates this * contract in its own constructor and contracts cannot be called while initializing. */ fyToken = fyToken_; } struct RedeemFyTokensLocalVars { MathError mathErr; uint256 newUnderlyingTotalSupply; uint256 underlyingPrecisionScalar; uint256 underlyingAmount; } /** * @notice Pays the token holder the face value at maturation time. * * @dev Emits a {RedeemFyTokens} event. * * Requirements: * * - Must be called after maturation. * - The amount to redeem cannot be zero. * - The Fintroller must allow this action to be performed. * - There must be enough liquidity in the Redemption Pool. * * @param fyTokenAmount The amount of fyTokens to redeem for the underlying asset. * @return bool true = success, otherwise it reverts. */ function redeemFyTokens(uint256 fyTokenAmount) external override nonReentrant returns (bool) { RedeemFyTokensLocalVars memory vars; /* Checks: maturation time. */ require(block.timestamp >= fyToken.expirationTime(), "ERR_BOND_NOT_MATURED"); /* Checks: the zero edge case. */ require(fyTokenAmount > 0, "ERR_REDEEM_FYTOKENS_ZERO"); /* Checks: the Fintroller allows this action to be performed. */ require(fintroller.getRedeemFyTokensAllowed(fyToken), "ERR_REDEEM_FYTOKENS_NOT_ALLOWED"); /** * fyTokens always have 18 decimals so the underlying amount needs to be downscaled. * If the precision scalar is 1, it means that the underlying also has 18 decimals. */ vars.underlyingPrecisionScalar = fyToken.underlyingPrecisionScalar(); if (vars.underlyingPrecisionScalar != 1) { (vars.mathErr, vars.underlyingAmount) = divUInt(fyTokenAmount, vars.underlyingPrecisionScalar); require(vars.mathErr == MathError.NO_ERROR, "ERR_REDEEM_FYTOKENS_MATH_ERROR"); } else { vars.underlyingAmount = fyTokenAmount; } /* Checks: there is enough liquidity. */ require(vars.underlyingAmount <= totalUnderlyingSupply, "ERR_REDEEM_FYTOKENS_INSUFFICIENT_UNDERLYING"); /* Effects: decrease the remaining supply of underlying. */ (vars.mathErr, vars.newUnderlyingTotalSupply) = subUInt(totalUnderlyingSupply, vars.underlyingAmount); assert(vars.mathErr == MathError.NO_ERROR); totalUnderlyingSupply = vars.newUnderlyingTotalSupply; /* Interactions: burn the fyTokens. */ require(fyToken.burn(msg.sender, fyTokenAmount), "ERR_SUPPLY_UNDERLYING_CALL_BURN"); /* Interactions: perform the Erc20 transfer. */ fyToken.underlying().safeTransfer(msg.sender, vars.underlyingAmount); emit RedeemFyTokens(msg.sender, fyTokenAmount, vars.underlyingAmount); return true; } struct SupplyUnderlyingLocalVars { MathError mathErr; uint256 fyTokenAmount; uint256 newUnderlyingTotalSupply; uint256 underlyingPrecisionScalar; } /** * @notice An alternative to the usual minting method that does not involve taking on debt. * * @dev Emits a {SupplyUnderlying} event. * * Requirements: * * - Must be called prior to maturation. * - The amount to supply cannot be zero. * - The Fintroller must allow this action to be performed. * - The caller must have allowed this contract to spend `underlyingAmount` tokens. * * @param underlyingAmount The amount of underlying to supply to the Redemption Pool. * @return bool true = success, otherwise it reverts. */ function supplyUnderlying(uint256 underlyingAmount) external override nonReentrant returns (bool) { SupplyUnderlyingLocalVars memory vars; /* Checks: maturation time. */ require(block.timestamp < fyToken.expirationTime(), "ERR_BOND_MATURED"); /* Checks: the zero edge case. */ require(underlyingAmount > 0, "ERR_SUPPLY_UNDERLYING_ZERO"); /* Checks: the Fintroller allows this action to be performed. */ require(fintroller.getSupplyUnderlyingAllowed(fyToken), "ERR_SUPPLY_UNDERLYING_NOT_ALLOWED"); /* Effects: update storage. */ (vars.mathErr, vars.newUnderlyingTotalSupply) = addUInt(totalUnderlyingSupply, underlyingAmount); require(vars.mathErr == MathError.NO_ERROR, "ERR_SUPPLY_UNDERLYING_MATH_ERROR"); totalUnderlyingSupply = vars.newUnderlyingTotalSupply; /** * fyTokens always have 18 decimals so the underlying amount needs to be upscaled. * If the precision scalar is 1, it means that the underlying also has 18 decimals. */ vars.underlyingPrecisionScalar = fyToken.underlyingPrecisionScalar(); if (vars.underlyingPrecisionScalar != 1) { (vars.mathErr, vars.fyTokenAmount) = mulUInt(underlyingAmount, vars.underlyingPrecisionScalar); require(vars.mathErr == MathError.NO_ERROR, "ERR_SUPPLY_UNDERLYING_MATH_ERROR"); } else { vars.fyTokenAmount = underlyingAmount; } /* Interactions: mint the fyTokens. */ require(fyToken.mint(msg.sender, vars.fyTokenAmount), "ERR_SUPPLY_UNDERLYING_CALL_MINT"); /* Interactions: perform the Erc20 transfer. */ fyToken.underlying().safeTransferFrom(msg.sender, address(this), underlyingAmount); emit SupplyUnderlying(msg.sender, underlyingAmount, vars.fyTokenAmount); return 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":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint256","name":"expirationTime_","type":"uint256"},{"internalType":"contract FintrollerInterface","name":"fintroller_","type":"address"},{"internalType":"contract BalanceSheetInterface","name":"balanceSheet_","type":"address"},{"internalType":"contract Erc20Interface","name":"underlying_","type":"address"},{"internalType":"contract Erc20Interface","name":"collateral_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"borrowAmount","type":"uint256"}],"name":"Borrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"indexed":false,"internalType":"uint256","name":"burnAmount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"liquidator","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"repayAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"clutchedCollateralAmount","type":"uint256"}],"name":"LiquidateBorrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"contract Erc20Interface","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"recoverAmount","type":"uint256"}],"name":"Recover","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"payer","type":"address"},{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"repayAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDebt","type":"uint256"}],"name":"RepayBorrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"contract FintrollerInterface","name":"oldFintroller","type":"address"},{"indexed":false,"internalType":"contract FintrollerInterface","name":"newFintroller","type":"address"}],"name":"SetFintroller","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"contract Erc20Interface[]","name":"nonRecoverableTokens","type":"address[]"}],"name":"SetNonRecoverableTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","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"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract Erc20Interface","name":"token","type":"address"},{"internalType":"uint256","name":"recoverAmount","type":"uint256"}],"name":"_recover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"_renounceAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract FintrollerInterface","name":"newFintroller","type":"address"}],"name":"_setFintroller","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Erc20Interface[]","name":"tokens","type":"address[]"}],"name":"_setNonRecoverableTokens","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":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceSheet","outputs":[{"internalType":"contract BalanceSheetInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"borrowAmount","type":"uint256"}],"name":"borrow","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"uint256","name":"burnAmount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collateral","outputs":[{"internalType":"contract Erc20Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateralPrecisionScalar","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"expirationTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fintroller","outputs":[{"internalType":"contract FintrollerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isFyToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMatured","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"repayAmount","type":"uint256"}],"name":"liquidateBorrow","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nonRecoverableTokens","outputs":[{"internalType":"contract Erc20Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redemptionPool","outputs":[{"internalType":"contract RedemptionPoolInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"repayAmount","type":"uint256"}],"name":"repayBorrow","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"repayAmount","type":"uint256"}],"name":"repayBorrowBehalf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"underlying","outputs":[{"internalType":"contract Erc20Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"underlyingPrecisionScalar","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620061cb380380620061cb833981810160405260e08110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060408181526020830151908301516060840151608085015160a0909501516000805460ff1916600117815560118054336101008102610100600160a81b0319909216919091179091559498509296509094939092899289926012928592859285929182917fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80908290a35082516200023890600b906020860190620007eb565b5081516200024e90600c906020850190620007eb565b50600a805460ff191660ff929092169190911790555050604051600b805446927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f929181908390600261010060018316150260001901909116048015620002ef5780601f10620002cc576101008083540402835291820191620002ef565b820191906000526020600020905b815481529060010190602001808311620002da575b505060408051918290038220828201825260018352603160f81b602093840152815180840196909652858201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606086015260808501959095523060a0808601919091528551808603909101815260c0850180875281519183019190912060085563313ce56760e01b9052935160129750600096506001600160a01b038a16955063313ce5679460c480860195919450919250829003018186803b158015620003b857600080fd5b505afa158015620003cd573d6000803e3d6000fd5b505050506040513d6020811015620003e457600080fd5b505160ff16905080620004295760405162461bcd60e51b8152600401808060200182810382526030815260200180620061336030913960400191505060405180910390fd5b8160ff168111156200046d5760405162461bcd60e51b8152600401808060200182810382526034815260200180620061976034913960400191505060405180910390fd5b808260ff1603600a0a60078190555083600660006101000a8154816001600160a01b0302191690836001600160a01b031602179055506000836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015620004df57600080fd5b505afa158015620004f4573d6000803e3d6000fd5b505050506040513d60208110156200050b57600080fd5b505160ff16905080620005505760405162461bcd60e51b8152600401808060200182810382526030815260200180620060d26030913960400191505060405180910390fd5b808360ff161015620005945760405162461bcd60e51b8152600401808060200182810382526034815260200180620061636034913960400191505060405180910390fd5b60ff8316819003600a0a600255600180546001600160a01b0319166001600160a01b038616179055428811620005fc5760405162461bcd60e51b8152600401808060200182810382526031815260200180620061026031913960400191505060405180910390fd5b6003889055600480546001600160a01b0319166001600160a01b03898116919091178083556040805163058f25c560e41b8152905191909216926358f25c5092808201926020929091829003018186803b1580156200065a57600080fd5b505afa1580156200066f573d6000803e3d6000fd5b505050506040513d60208110156200068657600080fd5b505060008054610100600160a81b0319166101006001600160a01b0389811682029290921792839055604080516318c8788360e21b815290519190930490911691636321e20c916004808301926020929190829003018186803b158015620006ed57600080fd5b505afa15801562000702573d6000803e3d6000fd5b505050506040513d60208110156200071957600080fd5b5050604051879030906200072d9062000880565b6001600160a01b03928316815291166020820152604080519182900301906000f08015801562000761573d6000803e3d6000fd5b50600580546001600160a01b0319166001600160a01b03928316179081905560408051637355dad760e11b81523360048201529051919092169163e6abb5ae91602480830192600092919082900301818387803b158015620007c257600080fd5b505af1158015620007d7573d6000803e3d6000fd5b5050505050505050505050505050620008a5565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200082357600085556200086e565b82601f106200083e57805160ff19168380011785556200086e565b828001600101855582156200086e579182015b828111156200086e57825182559160200191906001019062000851565b506200087c9291506200088e565b5090565b611d4c806200438683390190565b5b808211156200087c57600081556001016200088f565b613ad180620008b56000396000f3fe608060405234801561001057600080fd5b506004361061023d5760003560e01c80637ecebe001161013b578063cab364f1116100b8578063dde4bec01161007c578063dde4bec014610677578063e6abb5ae146106e5578063e6e0d75c1461070b578063ede4c0cc14610737578063f851a4401461073f5761023d565b8063cab364f1146105e0578063d505accf146105e8578063d8dfeb4514610639578063da284dcc14610641578063dd62ed3e146106495761023d565b8063a457c2d7116100ff578063a457c2d71461055b578063a9059cbb14610587578063b2bc5ef9146105b3578063bfa25308146105bb578063c5ebeaec146105c35761023d565b80637ecebe00146104dc5780637f2b6a0d1461050257806395d89b411461050a5780639dc29fac146105125780639e6ae5a01461053e5761023d565b80632608f818116101c957806340c10f191161018d57806340c10f191461047257806354fd4d501461049e5780636f307dc3146104a657806370a08231146104ae5780637c4950c7146104d45761023d565b80632608f818146103ec57806330adf81f14610418578063313ce567146104205780633644e5151461043e57806339509351146104465761023d565b80631a0de6fa116102105780631a0de6fa146103365780631c2872aa1461033e5780631eabf00d1461036c57806322285cf61461039257806323b872dd146103b65761023d565b806306fdde0314610242578063095ea7b3146102bf5780630e752702146102ff57806318160ddd1461031c575b600080fd5b61024a610747565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561028457818101518382015260200161026c565b50505050905090810190601f1680156102b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102eb600480360360408110156102d557600080fd5b506001600160a01b0381351690602001356107d5565b604080519115158252519081900360200190f35b6102eb6004803603602081101561031557600080fd5b50356107eb565b61032461092e565b60408051918252519081900360200190f35b610324610934565b61036a6004803603604081101561035457600080fd5b506001600160a01b03813516906020013561093a565b005b6102eb6004803603602081101561038257600080fd5b50356001600160a01b0316610d9d565b61039a610f1c565b604080516001600160a01b039092168252519081900360200190f35b6102eb600480360360608110156103cc57600080fd5b506001600160a01b03813581169160208101359091169060400135610f30565b6102eb6004803603604081101561040257600080fd5b506001600160a01b038135169060200135610fd5565b61032461111b565b61042861113f565b6040805160ff9092168252519081900360200190f35b610324611148565b6102eb6004803603604081101561045c57600080fd5b506001600160a01b03813516906020013561114e565b6102eb6004803603604081101561048857600080fd5b506001600160a01b0381351690602001356111e5565b61024a61132e565b61039a61134b565b610324600480360360208110156104c457600080fd5b50356001600160a01b031661135a565b61039a611375565b610324600480360360208110156104f257600080fd5b50356001600160a01b0316611384565b6102eb611396565b61024a61139f565b6102eb6004803603604081101561052857600080fd5b506001600160a01b0381351690602001356113fa565b61039a6004803603602081101561055457600080fd5b5035611543565b6102eb6004803603604081101561057157600080fd5b506001600160a01b03813516906020013561156d565b6102eb6004803603604081101561059d57600080fd5b506001600160a01b0381351690602001356115ee565b6103246115fb565b61036a611601565b6102eb600480360360208110156105d957600080fd5b50356116a5565b6102eb611e9f565b61036a600480360360e08110156105fe57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135611ea4565b61039a612159565b610324612168565b6103246004803603604081101561065f57600080fd5b506001600160a01b038135811691602001351661216e565b61036a6004803603602081101561068d57600080fd5b810190602081018135600160201b8111156106a757600080fd5b8201836020820111156106b957600080fd5b803590602001918460208302840111600160201b831117156106da57600080fd5b509092509050612199565b61036a600480360360208110156106fb57600080fd5b50356001600160a01b0316612460565b6102eb6004803603604081101561072157600080fd5b506001600160a01b038135169060200135612576565b61039a612aca565b61039a612ad9565b600b805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107cd5780601f106107a2576101008083540402835291602001916107cd565b820191906000526020600020905b8154815290600101906020018083116107b057829003601f168201915b505050505081565b60006107e2338484612aed565b50600192915050565b6000805460408051632d3caa7360e21b815230600482015233602482018190529151919261010090046001600160a01b03169163b4f2a9cc91604480820192602092909190829003018186803b15801561084457600080fd5b505afa158015610858573d6000803e3d6000fd5b505050506040513d602081101561086e57600080fd5b50516108b6576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff16610902576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff19169055610917338085612bd9565b60019150506000805460ff19166001179055919050565b600d5481565b60075481565b60115461010090046001600160a01b0316331461098e576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60115460ff1615156001146109df576040805162461bcd60e51b815260206004820152601260248201527111549497d393d517d253925510531256915160721b604482015290519081900360640190fd5b60008111610a27576040805162461bcd60e51b815260206004820152601060248201526f4552525f5245434f5645525f5a45524f60801b604482015290519081900360640190fd5b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015610a6257600080fd5b505afa158015610a76573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610a9f57600080fd5b8101908080516040519392919084600160201b821115610abe57600080fd5b908301906020820185811115610ad357600080fd5b8251600160201b811182820188101715610aec57600080fd5b82525081516020918201929091019080838360005b83811015610b19578181015183820152602001610b01565b50505050905090810190601f168015610b465780820380516001836020036101000a031916815260200191505b506040525050508051906020012090506000601080549050905060005b81811015610d275760108181548110610b7857fe5b6000918252602090912001546001600160a01b03868116911614801590610ce4575060108181548110610ba757fe5b6000918252602082200154604080516395d89b4160e01b815290516001600160a01b03909216926395d89b4192600480840193829003018186803b158015610bee57600080fd5b505afa158015610c02573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610c2b57600080fd5b8101908080516040519392919084600160201b821115610c4a57600080fd5b908301906020820185811115610c5f57600080fd5b8251600160201b811182820188101715610c7857600080fd5b82525081516020918201929091019080838360005b83811015610ca5578181015183820152602001610c8d565b50505050905090810190601f168015610cd25780820380516001836020036101000a031916815260200191505b50604052505050805190602001208314155b610d1f5760405162461bcd60e51b815260040180806020018281038252602181526020018061380d6021913960400191505060405180910390fd5b600101610b63565b50601154610d47906001600160a01b038681169161010090041685612f81565b601154604080516001600160a01b03878116825260208201879052825161010090940416927ff6891c84a6c6af32a6d052172a8acc4c631b1d5057ffa2bc1da268b6938ea2da929181900390910190a250505050565b60115460009061010090046001600160a01b03163314610df4576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b816001600160a01b03166358f25c506040518163ffffffff1660e01b815260040160206040518083038186803b158015610e2d57600080fd5b505afa158015610e41573d6000803e3d6000fd5b505050506040513d6020811015610e5757600080fd5b5051610eaa576040805162461bcd60e51b815260206004820152601d60248201527f4552525f5345545f46494e54524f4c4c45525f494e5350454354494f4e000000604482015290519081900360640190fd5b600480546001600160a01b038481166001600160a01b0319831681179093556011546040805193831680855260208501959095528051610100909204909216927f05f5eff078a94c026377ab6c6bdc6d2ad1932a3e4971fd7473348af3609ec57a92908290030190a250600192915050565b60005461010090046001600160a01b031681565b6000610f3d848484612fd8565b6001600160a01b0384166000908152600e602090815260408083203384529091528120548190610f6d908561316c565b90925090506000826004811115610f8057fe5b14610fbc5760405162461bcd60e51b815260040180806020018281038252602e815260200180613873602e913960400191505060405180910390fd5b610fc7863383612aed565b6001925050505b9392505050565b6000805460408051632d3caa7360e21b81523060048201526001600160a01b0386811660248301529151869361010090049092169163b4f2a9cc91604480820192602092909190829003018186803b15801561103057600080fd5b505afa158015611044573d6000803e3d6000fd5b505050506040513d602081101561105a57600080fd5b50516110a2576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff166110ee576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff19169055611103338585612bd9565b60019150506000805460ff1916600117905592915050565b7ffc77c2b9d30fe91687fd39abb7d16fcdfe1472d065740051ab8b13e4bf4a617f81565b600a5460ff1681565b60085481565b336000908152600e602090815260408083206001600160a01b0386168452909152812054819081906111809085613192565b9092509050600082600481111561119357fe5b146111cf5760405162461bcd60e51b81526004018080602001828103825260258152602001806138f16025913960400191505060405180910390fd5b6111da338683612aed565b506001949350505050565b6000805460ff16611232576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff191690556005546001600160a01b0316331461129b576040805162461bcd60e51b815260206004820152601760248201527f4552525f4d494e545f4e4f545f415554484f52495a4544000000000000000000604482015290519081900360640190fd5b600082116112e0576040805162461bcd60e51b815260206004820152600d60248201526c4552525f4d494e545f5a45524f60981b604482015290519081900360640190fd5b6112ea83836131b8565b6040805183815290516001600160a01b0385169130916000805160206139c98339815191529181900360200190a35060016000805460ff1916600117905592915050565b604051806040016040528060018152602001603160f81b81525081565b6006546001600160a01b031681565b6001600160a01b03166000908152600f602052604090205490565b6005546001600160a01b031681565b60096020526000908152604090205481565b60035442101590565b600c805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107cd5780601f106107a2576101008083540402835291602001916107cd565b6000805460ff16611447576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff191690556005546001600160a01b031633146114b0576040805162461bcd60e51b815260206004820152601760248201527f4552525f4255524e5f4e4f545f415554484f52495a4544000000000000000000604482015290519081900360640190fd5b600082116114f5576040805162461bcd60e51b815260206004820152600d60248201526c4552525f4255524e5f5a45524f60981b604482015290519081900360640190fd5b6114ff8383613306565b60408051838152905130916001600160a01b038616916000805160206139c98339815191529181900360200190a35060016000805460ff1916600117905592915050565b6010818154811061155357600080fd5b6000918252602090912001546001600160a01b0316905081565b336000908152600e602090815260408083206001600160a01b03861684529091528120548190819061159f908561316c565b909250905060008260048111156115b257fe5b146111cf5760405162461bcd60e51b81526004018080602001828103825260268152602001806137e76026913960400191505060405180910390fd5b60006107e2338484612fd8565b60025481565b60115461010090046001600160a01b03163314611655576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60115460405160009161010090046001600160a01b0316907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80908390a360118054610100600160a81b0319169055565b6000805460408051632d3caa7360e21b815230600482015233602482018190529151919261010090046001600160a01b03169163b4f2a9cc91604480820192602092909190829003018186803b1580156116fe57600080fd5b505afa158015611712573d6000803e3d6000fd5b505050506040513d602081101561172857600080fd5b5051611770576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff166117bc576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff191690556117ce6136e0565b6117d6611396565b1561181b576040805162461bcd60e51b815260206004820152601060248201526f11549497d093d39117d350551554915160821b604482015290519081900360640190fd5b60008411611862576040805162461bcd60e51b815260206004820152600f60248201526e4552525f424f52524f575f5a45524f60881b604482015290519081900360640190fd5b60048054604080516381a7bc9760e01b81523093810193909352516001600160a01b03909116916381a7bc97916024808301926020929190829003018186803b1580156118ae57600080fd5b505afa1580156118c2573d6000803e3d6000fd5b505050506040513d60208110156118d857600080fd5b5051611924576040805162461bcd60e51b815260206004820152601660248201527511549497d093d49493d5d7d393d517d0531313d5d15160521b604482015290519081900360640190fd5b611930600d5485613192565b60a083018190528282600481111561194457fe5b600481111561194f57fe5b905250600090508151600481111561196357fe5b146119ad576040805162461bcd60e51b815260206004820152601560248201527422a9292fa127a92927abafa6a0aa242fa2a92927a960591b604482015290519081900360640190fd5b600480546040805163d010b00f60e01b81523093810193909352516001600160a01b039091169163d010b00f916024808301926020929190829003018186803b1580156119f957600080fd5b505afa158015611a0d573d6000803e3d6000fd5b505050506040513d6020811015611a2357600080fd5b50516040820181905260a08201511115611a84576040805162461bcd60e51b815260206004820181905260248201527f4552525f424f52524f575f444542545f4345494c494e475f4f564552464c4f57604482015290519081900360640190fd5b6000546040805163bbd7edc560e01b815230600482015233602482015290516101009092046001600160a01b03169163bbd7edc591604480820192608092909190829003018186803b158015611ad957600080fd5b505afa158015611aed573d6000803e3d6000fd5b505050506040513d6080811015611b0357600080fd5b508051604090910151606083018190526020830191909152611b565760405162461bcd60e51b8152600401808060200182810382526021815260200180613a2d6021913960400191505060405180910390fd5b611b64816020015185613192565b60c0830181905282826004811115611b7857fe5b6004811115611b8357fe5b9052506000905081516004811115611b9757fe5b14611be1576040805162461bcd60e51b815260206004820152601560248201527422a9292fa127a92927abafa6a0aa242fa2a92927a960591b604482015290519081900360640190fd5b600054606082015160c08301516040805163d8e51dfb60e01b815230600482015233602482015260448101939093526064830191909152516101009092046001600160a01b03169163d8e51dfb91608480820192602092909190829003018186803b158015611c4f57600080fd5b505afa158015611c63573d6000803e3d6000fd5b505050506040513d6020811015611c7957600080fd5b50516080820152600480546040805163351da44160e21b81523093810193909352516001600160a01b039091169163d4769104916024808301926020929190829003018186803b158015611ccc57600080fd5b505afa158015611ce0573d6000803e3d6000fd5b505050506040513d6020811015611cf657600080fd5b505160e0820181905260808201511015611d415760405162461bcd60e51b81526004018080602001828103825260218152602001806137756021913960400191505060405180910390fd5b611d4b33856131b8565b604080518581529051339130916000805160206139c98339815191529181900360200190a36000805460c083015160408051630b9d2cc360e41b81523060048201523360248201526044810192909252516101009092046001600160a01b03169263b9d2cc30926064808401936020939083900390910190829087803b158015611dd457600080fd5b505af1158015611de8573d6000803e3d6000fd5b505050506040513d6020811015611dfe57600080fd5b5051611e51576040805162461bcd60e51b815260206004820152601e60248201527f4552525f424f52524f575f43414c4c5f5345545f5641554c545f444542540000604482015290519081900360640190fd5b60408051858152905133917fcbc04eca7e9da35cb1393a6135a199ca52e450d5e9251cbd99f7847d33a36750919081900360200190a26001925050506000805460ff19166001179055919050565b600181565b6001600160a01b038716611ee95760405162461bcd60e51b81526004018080602001828103825260238152602001806137526023913960400191505060405180910390fd5b6001600160a01b038616611f2e5760405162461bcd60e51b815260040180806020018281038252602581526020018061395d6025913960400191505060405180910390fd5b42841015611f83576040805162461bcd60e51b815260206004820152601860248201527f4552525f45524332305f5045524d49545f455850495245440000000000000000604482015290519081900360640190fd5b6001600160a01b0380881660008181526009602090815260408083208054600180820190925582517ffc77c2b9d30fe91687fd39abb7d16fcdfe1472d065740051ab8b13e4bf4a617f8186015280840196909652958c166060860152608085018b905260a085019590955260c08085018a90528151808603909101815260e08501825280519083012060085461190160f01b61010087015261010286015261012280860182905282518087039091018152610142860180845281519185019190912090859052610162860180845281905260ff8a166101828701526101a286018990526101c2860188905291519095919491926101e2808401939192601f1981019281900390910190855afa1580156120a0573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166120f25760405162461bcd60e51b815260040180806020018281038252602d8152602001806137ba602d913960400191505060405180910390fd5b896001600160a01b0316816001600160a01b0316146121425760405162461bcd60e51b81526004018080602001828103825260228152602001806139e96022913960400191505060405180910390fd5b61214d8a8a8a612aed565b50505050505050505050565b6001546001600160a01b031681565b60035481565b6001600160a01b039182166000908152600e6020908152604080832093909416825291909152205490565b60115461010090046001600160a01b031633146121ed576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60115460ff1615612236576040805162461bcd60e51b815260206004820152600e60248201526d11549497d253925510531256915160921b604482015290519081900360640190fd5b8060005b818110156123d35783838281811061224e57fe5b905060200201356001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561229657600080fd5b505afa1580156122aa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156122d357600080fd5b8101908080516040519392919084600160201b8211156122f257600080fd5b90830190602082018581111561230757600080fd5b8251600160201b81118282018810171561232057600080fd5b82525081516020918201929091019080838360005b8381101561234d578181015183820152602001612335565b50505050905090810190601f16801561237a5780820380516001836020036101000a031916815260200191505b5060405250505050601084848381811061239057fe5b835460018181018655600095865260209586902090910180546001600160a01b0319166001600160a01b039690930294909401359490941617909155500161223a565b5060118054600160ff1990911617908190556040805160208082528082018690526101009093046001600160a01b0316927fd877543bef27da9036243421e623413c8fdd78d7d183cc93d8f3cddbd657a2ed928792879290918291908201908590850280828437600083820152604051601f909101601f19169092018290039550909350505050a2505050565b60115461010090046001600160a01b031633146124b4576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b6001600160a01b03811661250f576040805162461bcd60e51b815260206004820152601a60248201527f4552525f5345545f41444d494e5f5a45524f5f41444452455353000000000000604482015290519081900360640190fd5b6011546040516001600160a01b0380841692610100900416907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf8090600090a3601180546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6000805460408051632d3caa7360e21b81523060048201526001600160a01b0386811660248301529151869361010090049092169163b4f2a9cc91604480820192602092909190829003018186803b1580156125d157600080fd5b505afa1580156125e5573d6000803e3d6000fd5b505050506040513d60208110156125fb57600080fd5b5051612643576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff1661268f576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff191690556126a1613726565b336001600160a01b03861614156126ff576040805162461bcd60e51b815260206004820152601960248201527f4552525f4c49515549444154455f424f52524f575f53454c4600000000000000604482015290519081900360640190fd5b60008411612754576040805162461bcd60e51b815260206004820152601960248201527f4552525f4c49515549444154455f424f52524f575f5a45524f00000000000000604482015290519081900360640190fd5b6004805460408051632ec8fffb60e21b81523093810193909352516001600160a01b039091169163bb23ffec916024808301926020929190829003018186803b1580156127a057600080fd5b505afa1580156127b4573d6000803e3d6000fd5b505050506040513d60208110156127ca57600080fd5b505161281d576040805162461bcd60e51b815260206004820181905260248201527f4552525f4c49515549444154455f424f52524f575f4e4f545f414c4c4f574544604482015290519081900360640190fd5b612825611396565b6129085760005460408051639ee91d1f60e01b81523060048201526001600160a01b038881166024830152915161010090930490911691639ee91d1f91604480820192602092909190829003018186803b15801561288257600080fd5b505afa158015612896573d6000803e3d6000fd5b505050506040513d60208110156128ac57600080fd5b5051151560608201819052612908576040805162461bcd60e51b815260206004820152601a60248201527f4552525f4143434f554e545f4e4f545f554e4445525741544552000000000000604482015290519081900360640190fd5b612913338686612bd9565b600080546040805163464b048560e01b81523060048201526024810188905290516101009092046001600160a01b03169163464b048591604480820192602092909190829003018186803b15801561296a57600080fd5b505afa15801561297e573d6000803e3d6000fd5b505050506040513d602081101561299457600080fd5b50516000805460408051630e496ef360e01b81523060048201523360248201526001600160a01b038b811660448301526064820186905291519495506101009092041692630e496ef392608480840193602093929083900390910190829087803b158015612a0157600080fd5b505af1158015612a15573d6000803e3d6000fd5b505050506040513d6020811015612a2b57600080fd5b5051612a685760405162461bcd60e51b815260040180806020018281038252602b8152602001806138a1602b913960400191505060405180910390fd5b604080518681526020810183905281516001600160a01b0389169233927f08b197b6ae66d18ee6fa20a826a84579a925b9e646a3bf19e96f59ed568c2688929081900390910190a3600193505050506000805460ff1916600117905592915050565b6004546001600160a01b031681565b60115461010090046001600160a01b031681565b6001600160a01b038316612b325760405162461bcd60e51b8152600401808060200182810382526023815260200180613a796023913960400191505060405180910390fd5b6001600160a01b038216612b775760405162461bcd60e51b815260040180806020018281038252602181526020018061382e6021913960400191505060405180910390fd5b6001600160a01b038084166000818152600e6020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b60008111612c26576040805162461bcd60e51b81526020600482015260156024820152744552525f52455041595f424f52524f575f5a45524f60581b604482015290519081900360640190fd5b600480546040805163e60f077360e01b81523093810193909352516001600160a01b039091169163e60f0773916024808301926020929190829003018186803b158015612c7257600080fd5b505afa158015612c86573d6000803e3d6000fd5b505050506040513d6020811015612c9c57600080fd5b5051612cef576040805162461bcd60e51b815260206004820152601c60248201527f4552525f52455041595f424f52524f575f4e4f545f414c4c4f57454400000000604482015290519081900360640190fd5b6000805460408051638a0695fd60e01b81523060048201526001600160a01b038681166024830152915161010090930490911691638a0695fd91604480820192602092909190829003018186803b158015612d4957600080fd5b505afa158015612d5d573d6000803e3d6000fd5b505050506040513d6020811015612d7357600080fd5b5051905081811015612db65760405162461bcd60e51b815260040180806020018281038252602281526020018061393b6022913960400191505060405180910390fd5b81612dc08561135a565b1015612dfd5760405162461bcd60e51b81526004018080602001828103825260258152602001806139166025913960400191505060405180910390fd5b612e078483613306565b60408051838152905130916001600160a01b038716916000805160206139c98339815191529181900360200190a3600080612e42838561316c565b90925090506000826004811115612e5557fe5b14612e5c57fe5b6000805460408051630b9d2cc360e41b81523060048201526001600160a01b0389811660248301526044820186905291516101009093049091169263b9d2cc30926064808401936020939083900390910190829087803b158015612ebf57600080fd5b505af1158015612ed3573d6000803e3d6000fd5b505050506040513d6020811015612ee957600080fd5b5051612f265760405162461bcd60e51b81526004018080602001828103825260248152602001806139826024913960400191505060405180910390fd5b846001600160a01b0316866001600160a01b03167fa9a154237a69922f8860321d1fec1624a5dbe8a8af89a3dd3d7a759f6c8080d88684604051808381526020018281526020019250505060405180910390a3505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612fd3908490613454565b505050565b6001600160a01b03831661301d5760405162461bcd60e51b815260040180806020018281038252602481526020018061384f6024913960400191505060405180910390fd5b6001600160a01b0382166130625760405162461bcd60e51b8152600401808060200182810382526022815260200180613a0b6022913960400191505060405180910390fd5b6001600160a01b0383166000908152600f602052604081205481908190613089908561316c565b9093509150600083600481111561309c57fe5b146130d85760405162461bcd60e51b815260040180806020018281038252602b815260200180613a4e602b913960400191505060405180910390fd5b6001600160a01b038087166000908152600f6020526040808220859055918716815220546131069085613192565b9093509050600083600481111561311957fe5b1461312057fe5b6001600160a01b038086166000818152600f60209081526040918290208590558151888152915192938a16926000805160206139c98339815191529281900390910190a3505050505050565b60008083831161318357506000905081830361318b565b506003905060005b9250929050565b6000808383018481106131aa5760009250905061318b565b60026000925092505061318b565b6001600160a01b0382166000908152600f6020526040812054819081906131df9085613192565b909350915060008360048111156131f257fe5b14613244576040805162461bcd60e51b815260206004820152601f60248201527f4552525f45524332305f4d494e545f42414c414e43455f4f564552464c4f5700604482015290519081900360640190fd5b6001600160a01b0385166000908152600f60205260409020829055600d5461326c9085613192565b9093509050600083600481111561327f57fe5b146132bb5760405162461bcd60e51b81526004018080602001828103825260248152602001806137966024913960400191505060405180910390fd5b600d8190556040805185815290516001600160a01b038716917f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885919081900360200190a25050505050565b6001600160a01b0382166000908152600f60205260408120548190819061332d908561316c565b9093509150600083600481111561334057fe5b14613392576040805162461bcd60e51b815260206004820181905260248201527f4552525f45524332305f4255524e5f42414c414e43455f554e444552464c4f57604482015290519081900360640190fd5b6001600160a01b0385166000908152600f60205260409020829055600d546133ba908561316c565b909350905060008360048111156133cd57fe5b146134095760405162461bcd60e51b81526004018080602001828103825260258152602001806138cc6025913960400191505060405180910390fd5b600d8190556040805185815290516001600160a01b038716917fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5919081900360200190a25050505050565b600061349683836040518060400160405280601d81526020017f4552525f534146455f45524332305f4c4f575f4c4556454c5f43414c4c000000815250613508565b805190915015612fd3578080602001905160208110156134b557600080fd5b5051612fd3576040805162461bcd60e51b815260206004820152601e60248201527f4552525f534146455f45524332305f45524332305f4f5045524154494f4e0000604482015290519081900360640190fd5b606061351c846001600160a01b03166136a4565b6135575760405162461bcd60e51b81526004018080602001828103825260238152602001806139a66023913960400191505060405180910390fd5b600080856001600160a01b0316856040518082805190602001908083835b602083106135945780518252601f199092019160209182019101613575565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146135f6576040519150601f19603f3d011682016040523d82523d6000602084013e6135fb565b606091505b5091509150811561360f579150610fce9050565b80511561361f5780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613669578181015183820152602001613651565b50505050905090810190601f1680156136965780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906136d857508115155b949350505050565b6040805161010081019091528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604080516080810190915280600081526020016000815260200160008152602001600015158152509056fe4552525f45524332305f5045524d49545f4f574e45525f5a45524f5f414444524553534552525f42454c4f575f434f4c4c41544552414c495a4154494f4e5f524154494f4552525f45524332305f4d494e545f544f54414c5f535550504c595f4f564552464c4f574552525f45524332305f5045524d49545f5245434f56455245445f4f574e45525f5a45524f5f414444524553534552525f45524332305f44454352454153455f414c4c4f57414e43455f554e444552464c4f574552525f5245434f5645525f4e4f4e5f5245434f56455241424c455f544f4b454e4552525f45524332305f415050524f56455f544f5f5a45524f5f414444524553534552525f45524332305f5452414e534645525f46524f4d5f5a45524f5f414444524553534552525f45524332305f5452414e534645525f46524f4d5f494e53554646494349454e545f414c4c4f57414e43454552525f4c49515549444154455f424f52524f575f43414c4c5f434c555443485f434f4c4c41544552414c4552525f45524332305f4255524e5f544f54414c5f535550504c595f554e444552464c4f574552525f45524332305f494e4352454153455f414c4c4f57414e43455f4f564552464c4f574552525f52455041595f424f52524f575f494e53554646494349454e545f42414c414e43454552525f52455041595f424f52524f575f494e53554646494349454e545f444542544552525f45524332305f5045524d49545f5350454e4445525f5a45524f5f414444524553534552525f52455041595f424f52524f575f43414c4c5f5345545f5641554c545f444542544552525f534146455f45524332305f43414c4c5f544f5f4e4f4e5f434f4e5452414354ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef4552525f45524332305f5045524d49545f494e56414c49445f5349474e41545552454552525f45524332305f5452414e534645525f544f5f5a45524f5f414444524553534552525f424f52524f575f4c4f434b45445f434f4c4c41544552414c5f5a45524f4552525f45524332305f5452414e534645525f53454e4445525f42414c414e43455f554e444552464c4f574552525f45524332305f415050524f56455f46524f4d5f5a45524f5f41444452455353a26469706673582212208cee194c7873c76d0f278e0c8b44232bda5b534513841a90b49f26680b23561664736f6c63430007060033608060405234801561001057600080fd5b50604051611d4c380380611d4c8339818101604052604081101561003357600080fd5b5080516020909101516000805460ff1916600117815560048054336101008102610100600160a81b031990921691909117909155604051909182917fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80908290a35081600060016101000a8154816001600160a01b0302191690836001600160a01b03160217905550600060019054906101000a90046001600160a01b03166001600160a01b03166358f25c506040518163ffffffff1660e01b815260040160206040518083038186803b15801561010957600080fd5b505afa15801561011d573d6000803e3d6000fd5b505050506040513d602081101561013357600080fd5b5050600280546001600160a01b0319166001600160a01b039290921691909117905550611be7806101656000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063dde4bec011610071578063dde4bec014610166578063e02dcb17146101d4578063e6abb5ae146101f1578063ede4c0cc14610217578063f1374d181461021f578063f851a4401461023c576100b4565b8063143a08d4146100b95780631c2872aa146100d357806373805ae2146101015780639e6ae5a01461011d578063bfa2530814610156578063dc3bfba91461015e575b600080fd5b6100c1610244565b60408051918252519081900360200190f35b6100ff600480360360408110156100e957600080fd5b506001600160a01b03813516906020013561024a565b005b6101096106ad565b604080519115158252519081900360200190f35b61013a6004803603602081101561013357600080fd5b50356106b2565b604080516001600160a01b039092168252519081900360200190f35b6100ff6106dc565b61013a610780565b6100ff6004803603602081101561017c57600080fd5b810190602081018135600160201b81111561019657600080fd5b8201836020820111156101a857600080fd5b803590602001918460208302840111600160201b831117156101c957600080fd5b50909250905061078f565b610109600480360360208110156101ea57600080fd5b5035610a56565b6100ff6004803603602081101561020757600080fd5b50356001600160a01b0316611018565b61013a61112e565b6101096004803603602081101561023557600080fd5b5035611142565b61013a6116e6565b60015481565b60045461010090046001600160a01b0316331461029e576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60045460ff1615156001146102ef576040805162461bcd60e51b815260206004820152601260248201527111549497d393d517d253925510531256915160721b604482015290519081900360640190fd5b60008111610337576040805162461bcd60e51b815260206004820152601060248201526f4552525f5245434f5645525f5a45524f60801b604482015290519081900360640190fd5b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561037257600080fd5b505afa158015610386573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156103af57600080fd5b8101908080516040519392919084600160201b8211156103ce57600080fd5b9083019060208201858111156103e357600080fd5b8251600160201b8111828201881017156103fc57600080fd5b82525081516020918201929091019080838360005b83811015610429578181015183820152602001610411565b50505050905090810190601f1680156104565780820380516001836020036101000a031916815260200191505b506040525050508051906020012090506000600380549050905060005b81811015610637576003818154811061048857fe5b6000918252602090912001546001600160a01b038681169116148015906105f45750600381815481106104b757fe5b6000918252602082200154604080516395d89b4160e01b815290516001600160a01b03909216926395d89b4192600480840193829003018186803b1580156104fe57600080fd5b505afa158015610512573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561053b57600080fd5b8101908080516040519392919084600160201b82111561055a57600080fd5b90830190602082018581111561056f57600080fd5b8251600160201b81118282018810171561058857600080fd5b82525081516020918201929091019080838360005b838110156105b557818101518382015260200161059d565b50505050905090810190601f1680156105e25780820380516001836020036101000a031916815260200191505b50604052505050805190602001208314155b61062f5760405162461bcd60e51b8152600401808060200182810382526021815260200180611b226021913960400191505060405180910390fd5b600101610473565b50600454610657906001600160a01b0386811691610100900416856116fa565b600454604080516001600160a01b03878116825260208201879052825161010090940416927ff6891c84a6c6af32a6d052172a8acc4c631b1d5057ffa2bc1da268b6938ea2da929181900390910190a250505050565b600181565b600381815481106106c257600080fd5b6000918252602090912001546001600160a01b0316905081565b60045461010090046001600160a01b03163314610730576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60045460405160009161010090046001600160a01b0316907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80908390a360048054610100600160a81b0319169055565b6002546001600160a01b031681565b60045461010090046001600160a01b031633146107e3576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60045460ff161561082c576040805162461bcd60e51b815260206004820152600e60248201526d11549497d253925510531256915160921b604482015290519081900360640190fd5b8060005b818110156109c95783838281811061084457fe5b905060200201356001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561088c57600080fd5b505afa1580156108a0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156108c957600080fd5b8101908080516040519392919084600160201b8211156108e857600080fd5b9083019060208201858111156108fd57600080fd5b8251600160201b81118282018810171561091657600080fd5b82525081516020918201929091019080838360005b8381101561094357818101518382015260200161092b565b50505050905090810190601f1680156109705780820380516001836020036101000a031916815260200191505b5060405250505050600384848381811061098657fe5b835460018181018655600095865260209586902090910180546001600160a01b0319166001600160a01b0396909302949094013594909416179091555001610830565b5060048054600160ff1990911617908190556040805160208082528082018690526101009093046001600160a01b0316927fd877543bef27da9036243421e623413c8fdd78d7d183cc93d8f3cddbd657a2ed928792879290918291908201908590850280828437600083820152604051601f909101601f19169092018290039550909350505050a2505050565b6000805460ff16610aa3576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff19169055610ab5611af8565b600260009054906101000a90046001600160a01b03166001600160a01b031663da284dcc6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0357600080fd5b505afa158015610b17573d6000803e3d6000fd5b505050506040513d6020811015610b2d57600080fd5b5051421015610b7a576040805162461bcd60e51b815260206004820152601460248201527311549497d093d39117d393d517d350551554915160621b604482015290519081900360640190fd5b60008311610bcf576040805162461bcd60e51b815260206004820152601860248201527f4552525f52454445454d5f4659544f4b454e535f5a45524f0000000000000000604482015290519081900360640190fd5b6000546002546040805163162fdba360e01b81526001600160a01b03928316600482015290516101009093049091169163162fdba391602480820192602092909190829003018186803b158015610c2557600080fd5b505afa158015610c39573d6000803e3d6000fd5b505050506040513d6020811015610c4f57600080fd5b5051610ca2576040805162461bcd60e51b815260206004820152601f60248201527f4552525f52454445454d5f4659544f4b454e535f4e4f545f414c4c4f57454400604482015290519081900360640190fd5b600260009054906101000a90046001600160a01b03166001600160a01b0316631a0de6fa6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cf057600080fd5b505afa158015610d04573d6000803e3d6000fd5b505050506040513d6020811015610d1a57600080fd5b505160408201819052600114610dc257610d38838260400151611751565b6060830181905282826004811115610d4c57fe5b6004811115610d5757fe5b9052506000905081516004811115610d6b57fe5b14610dbd576040805162461bcd60e51b815260206004820152601e60248201527f4552525f52454445454d5f4659544f4b454e535f4d4154485f4552524f520000604482015290519081900360640190fd5b610dca565b606081018390525b60015481606001511115610e0f5760405162461bcd60e51b815260040180806020018281038252602b815260200180611b43602b913960400191505060405180910390fd5b610e1f600154826060015161177d565b6020830181905282826004811115610e3357fe5b6004811115610e3e57fe5b9052506000905081516004811115610e5257fe5b14610e5957fe5b60208082015160015560025460408051632770a7eb60e21b81523360048201526024810187905290516001600160a01b0390921692639dc29fac926044808401938290030181600087803b158015610eb057600080fd5b505af1158015610ec4573d6000803e3d6000fd5b505050506040513d6020811015610eda57600080fd5b5051610f2d576040805162461bcd60e51b815260206004820152601f60248201527f4552525f535550504c595f554e4445524c59494e475f43414c4c5f4255524e00604482015290519081900360640190fd5b610fc0338260600151600260009054906101000a90046001600160a01b03166001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8457600080fd5b505afa158015610f98573d6000803e3d6000fd5b505050506040513d6020811015610fae57600080fd5b50516001600160a01b031691906116fa565b6060810151604080518581526020810192909252805133927f885a0ef214a8c0b5d41cbf3cd2292d459773279061790ae6c1e654483828048792908290030190a260019150506000805460ff19166001179055919050565b60045461010090046001600160a01b0316331461106c576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b6001600160a01b0381166110c7576040805162461bcd60e51b815260206004820152601a60248201527f4552525f5345545f41444d494e5f5a45524f5f41444452455353000000000000604482015290519081900360640190fd5b6004546040516001600160a01b0380841692610100900416907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf8090600090a3600480546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60005461010090046001600160a01b031681565b6000805460ff1661118f576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff191690556111a1611af8565b600260009054906101000a90046001600160a01b03166001600160a01b031663da284dcc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156111ef57600080fd5b505afa158015611203573d6000803e3d6000fd5b505050506040513d602081101561121957600080fd5b50514210611261576040805162461bcd60e51b815260206004820152601060248201526f11549497d093d39117d350551554915160821b604482015290519081900360640190fd5b600083116112b6576040805162461bcd60e51b815260206004820152601a60248201527f4552525f535550504c595f554e4445524c59494e475f5a45524f000000000000604482015290519081900360640190fd5b6000546002546040805163e79628ab60e01b81526001600160a01b03928316600482015290516101009093049091169163e79628ab91602480820192602092909190829003018186803b15801561130c57600080fd5b505afa158015611320573d6000803e3d6000fd5b505050506040513d602081101561133657600080fd5b50516113735760405162461bcd60e51b8152600401808060200182810382526021815260200180611b6e6021913960400191505060405180910390fd5b61137f600154846117a0565b604083018190528282600481111561139357fe5b600481111561139e57fe5b90525060009050815160048111156113b257fe5b14611404576040805162461bcd60e51b815260206004820181905260248201527f4552525f535550504c595f554e4445524c59494e475f4d4154485f4552524f52604482015290519081900360640190fd5b6040808201516001556002548151630d06f37d60e11b815291516001600160a01b0390911691631a0de6fa916004808301926020929190829003018186803b15801561144f57600080fd5b505afa158015611463573d6000803e3d6000fd5b505050506040513d602081101561147957600080fd5b505160608201819052600114611521576114978382606001516117c6565b60208301819052828260048111156114ab57fe5b60048111156114b657fe5b90525060009050815160048111156114ca57fe5b1461151c576040805162461bcd60e51b815260206004820181905260248201527f4552525f535550504c595f554e4445524c59494e475f4d4154485f4552524f52604482015290519081900360640190fd5b611529565b602081018390525b600254602080830151604080516340c10f1960e01b81523360048201526024810192909252516001600160a01b03909316926340c10f19926044808401939192918290030181600087803b15801561158057600080fd5b505af1158015611594573d6000803e3d6000fd5b505050506040513d60208110156115aa57600080fd5b50516115fd576040805162461bcd60e51b815260206004820152601f60248201527f4552525f535550504c595f554e4445524c59494e475f43414c4c5f4d494e5400604482015290519081900360640190fd5b61168e333085600260009054906101000a90046001600160a01b03166001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561165157600080fd5b505afa158015611665573d6000803e3d6000fd5b505050506040513d602081101561167b57600080fd5b50516001600160a01b0316929190611805565b6020808201516040805186815292830191909152805133927fc460d7cbd3e39052de48c19518b5af10728a5349bc2870e47b5a67ffc32d200d92908290030190a260019150506000805460ff19166001179055919050565b60045461010090046001600160a01b031681565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261174c908490611865565b505050565b600080826117655750600190506000611776565b600083858161177057fe5b04915091505b9250929050565b600080838311611794575060009050818303611776565b50600390506000611776565b6000808383018481106117b857600092509050611776565b600260009250925050611776565b600080836117d957506000905080611776565b838302838582816117e657fe5b04146117fa57600260009250925050611776565b600092509050611776565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261185f908590611865565b50505050565b60006118a783836040518060400160405280601d81526020017f4552525f534146455f45524332305f4c4f575f4c4556454c5f43414c4c000000815250611919565b80519091501561174c578080602001905160208110156118c657600080fd5b505161174c576040805162461bcd60e51b815260206004820152601e60248201527f4552525f534146455f45524332305f45524332305f4f5045524154494f4e0000604482015290519081900360640190fd5b606061192d846001600160a01b0316611abc565b6119685760405162461bcd60e51b8152600401808060200182810382526023815260200180611b8f6023913960400191505060405180910390fd5b600080856001600160a01b0316856040518082805190602001908083835b602083106119a55780518252601f199092019160209182019101611986565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611a07576040519150601f19603f3d011682016040523d82523d6000602084013e611a0c565b606091505b50915091508115611a20579150611ab59050565b805115611a305780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611a7a578181015183820152602001611a62565b50505050905090810190601f168015611aa75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611af057508115155b949350505050565b60408051608081019091528060008152602001600081526020016000815260200160008152509056fe4552525f5245434f5645525f4e4f4e5f5245434f56455241424c455f544f4b454e4552525f52454445454d5f4659544f4b454e535f494e53554646494349454e545f554e4445524c59494e474552525f535550504c595f554e4445524c59494e475f4e4f545f414c4c4f5745444552525f534146455f45524332305f43414c4c5f544f5f4e4f4e5f434f4e5452414354a2646970667358221220504e7960f16a46f68ab102d0a6c00cc3b4e3021515e5b688b79030739924e0a964736f6c634300070600334552525f4659544f4b454e5f434f4e5354525543544f525f434f4c4c41544552414c5f444543494d414c535f5a45524f4552525f4659544f4b454e5f434f4e5354525543544f525f45585049524154494f4e5f54494d455f4e4f545f56414c49444552525f4659544f4b454e5f434f4e5354525543544f525f554e4445524c59494e475f444543494d414c535f5a45524f4552525f4659544f4b454e5f434f4e5354525543544f525f434f4c4c41544552414c5f444543494d414c535f4f564552464c4f574552525f4659544f4b454e5f434f4e5354525543544f525f554e4445524c59494e475f444543494d414c535f4f564552464c4f5700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000060650d00000000000000000000000000ed4348fc8b1b634b3a0eadabfd32530046b89c6000000000000000000000000098e06ff5d4d43ca77772004a65022725d56a5a16000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000000000000000000000000000000000000000000164869666920555344432028323032322d30332d33312900000000000000000000000000000000000000000000000000000000000000000000000000000000000a685553444332324d617200000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061023d5760003560e01c80637ecebe001161013b578063cab364f1116100b8578063dde4bec01161007c578063dde4bec014610677578063e6abb5ae146106e5578063e6e0d75c1461070b578063ede4c0cc14610737578063f851a4401461073f5761023d565b8063cab364f1146105e0578063d505accf146105e8578063d8dfeb4514610639578063da284dcc14610641578063dd62ed3e146106495761023d565b8063a457c2d7116100ff578063a457c2d71461055b578063a9059cbb14610587578063b2bc5ef9146105b3578063bfa25308146105bb578063c5ebeaec146105c35761023d565b80637ecebe00146104dc5780637f2b6a0d1461050257806395d89b411461050a5780639dc29fac146105125780639e6ae5a01461053e5761023d565b80632608f818116101c957806340c10f191161018d57806340c10f191461047257806354fd4d501461049e5780636f307dc3146104a657806370a08231146104ae5780637c4950c7146104d45761023d565b80632608f818146103ec57806330adf81f14610418578063313ce567146104205780633644e5151461043e57806339509351146104465761023d565b80631a0de6fa116102105780631a0de6fa146103365780631c2872aa1461033e5780631eabf00d1461036c57806322285cf61461039257806323b872dd146103b65761023d565b806306fdde0314610242578063095ea7b3146102bf5780630e752702146102ff57806318160ddd1461031c575b600080fd5b61024a610747565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561028457818101518382015260200161026c565b50505050905090810190601f1680156102b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102eb600480360360408110156102d557600080fd5b506001600160a01b0381351690602001356107d5565b604080519115158252519081900360200190f35b6102eb6004803603602081101561031557600080fd5b50356107eb565b61032461092e565b60408051918252519081900360200190f35b610324610934565b61036a6004803603604081101561035457600080fd5b506001600160a01b03813516906020013561093a565b005b6102eb6004803603602081101561038257600080fd5b50356001600160a01b0316610d9d565b61039a610f1c565b604080516001600160a01b039092168252519081900360200190f35b6102eb600480360360608110156103cc57600080fd5b506001600160a01b03813581169160208101359091169060400135610f30565b6102eb6004803603604081101561040257600080fd5b506001600160a01b038135169060200135610fd5565b61032461111b565b61042861113f565b6040805160ff9092168252519081900360200190f35b610324611148565b6102eb6004803603604081101561045c57600080fd5b506001600160a01b03813516906020013561114e565b6102eb6004803603604081101561048857600080fd5b506001600160a01b0381351690602001356111e5565b61024a61132e565b61039a61134b565b610324600480360360208110156104c457600080fd5b50356001600160a01b031661135a565b61039a611375565b610324600480360360208110156104f257600080fd5b50356001600160a01b0316611384565b6102eb611396565b61024a61139f565b6102eb6004803603604081101561052857600080fd5b506001600160a01b0381351690602001356113fa565b61039a6004803603602081101561055457600080fd5b5035611543565b6102eb6004803603604081101561057157600080fd5b506001600160a01b03813516906020013561156d565b6102eb6004803603604081101561059d57600080fd5b506001600160a01b0381351690602001356115ee565b6103246115fb565b61036a611601565b6102eb600480360360208110156105d957600080fd5b50356116a5565b6102eb611e9f565b61036a600480360360e08110156105fe57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135611ea4565b61039a612159565b610324612168565b6103246004803603604081101561065f57600080fd5b506001600160a01b038135811691602001351661216e565b61036a6004803603602081101561068d57600080fd5b810190602081018135600160201b8111156106a757600080fd5b8201836020820111156106b957600080fd5b803590602001918460208302840111600160201b831117156106da57600080fd5b509092509050612199565b61036a600480360360208110156106fb57600080fd5b50356001600160a01b0316612460565b6102eb6004803603604081101561072157600080fd5b506001600160a01b038135169060200135612576565b61039a612aca565b61039a612ad9565b600b805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107cd5780601f106107a2576101008083540402835291602001916107cd565b820191906000526020600020905b8154815290600101906020018083116107b057829003601f168201915b505050505081565b60006107e2338484612aed565b50600192915050565b6000805460408051632d3caa7360e21b815230600482015233602482018190529151919261010090046001600160a01b03169163b4f2a9cc91604480820192602092909190829003018186803b15801561084457600080fd5b505afa158015610858573d6000803e3d6000fd5b505050506040513d602081101561086e57600080fd5b50516108b6576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff16610902576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff19169055610917338085612bd9565b60019150506000805460ff19166001179055919050565b600d5481565b60075481565b60115461010090046001600160a01b0316331461098e576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60115460ff1615156001146109df576040805162461bcd60e51b815260206004820152601260248201527111549497d393d517d253925510531256915160721b604482015290519081900360640190fd5b60008111610a27576040805162461bcd60e51b815260206004820152601060248201526f4552525f5245434f5645525f5a45524f60801b604482015290519081900360640190fd5b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015610a6257600080fd5b505afa158015610a76573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610a9f57600080fd5b8101908080516040519392919084600160201b821115610abe57600080fd5b908301906020820185811115610ad357600080fd5b8251600160201b811182820188101715610aec57600080fd5b82525081516020918201929091019080838360005b83811015610b19578181015183820152602001610b01565b50505050905090810190601f168015610b465780820380516001836020036101000a031916815260200191505b506040525050508051906020012090506000601080549050905060005b81811015610d275760108181548110610b7857fe5b6000918252602090912001546001600160a01b03868116911614801590610ce4575060108181548110610ba757fe5b6000918252602082200154604080516395d89b4160e01b815290516001600160a01b03909216926395d89b4192600480840193829003018186803b158015610bee57600080fd5b505afa158015610c02573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610c2b57600080fd5b8101908080516040519392919084600160201b821115610c4a57600080fd5b908301906020820185811115610c5f57600080fd5b8251600160201b811182820188101715610c7857600080fd5b82525081516020918201929091019080838360005b83811015610ca5578181015183820152602001610c8d565b50505050905090810190601f168015610cd25780820380516001836020036101000a031916815260200191505b50604052505050805190602001208314155b610d1f5760405162461bcd60e51b815260040180806020018281038252602181526020018061380d6021913960400191505060405180910390fd5b600101610b63565b50601154610d47906001600160a01b038681169161010090041685612f81565b601154604080516001600160a01b03878116825260208201879052825161010090940416927ff6891c84a6c6af32a6d052172a8acc4c631b1d5057ffa2bc1da268b6938ea2da929181900390910190a250505050565b60115460009061010090046001600160a01b03163314610df4576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b816001600160a01b03166358f25c506040518163ffffffff1660e01b815260040160206040518083038186803b158015610e2d57600080fd5b505afa158015610e41573d6000803e3d6000fd5b505050506040513d6020811015610e5757600080fd5b5051610eaa576040805162461bcd60e51b815260206004820152601d60248201527f4552525f5345545f46494e54524f4c4c45525f494e5350454354494f4e000000604482015290519081900360640190fd5b600480546001600160a01b038481166001600160a01b0319831681179093556011546040805193831680855260208501959095528051610100909204909216927f05f5eff078a94c026377ab6c6bdc6d2ad1932a3e4971fd7473348af3609ec57a92908290030190a250600192915050565b60005461010090046001600160a01b031681565b6000610f3d848484612fd8565b6001600160a01b0384166000908152600e602090815260408083203384529091528120548190610f6d908561316c565b90925090506000826004811115610f8057fe5b14610fbc5760405162461bcd60e51b815260040180806020018281038252602e815260200180613873602e913960400191505060405180910390fd5b610fc7863383612aed565b6001925050505b9392505050565b6000805460408051632d3caa7360e21b81523060048201526001600160a01b0386811660248301529151869361010090049092169163b4f2a9cc91604480820192602092909190829003018186803b15801561103057600080fd5b505afa158015611044573d6000803e3d6000fd5b505050506040513d602081101561105a57600080fd5b50516110a2576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff166110ee576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff19169055611103338585612bd9565b60019150506000805460ff1916600117905592915050565b7ffc77c2b9d30fe91687fd39abb7d16fcdfe1472d065740051ab8b13e4bf4a617f81565b600a5460ff1681565b60085481565b336000908152600e602090815260408083206001600160a01b0386168452909152812054819081906111809085613192565b9092509050600082600481111561119357fe5b146111cf5760405162461bcd60e51b81526004018080602001828103825260258152602001806138f16025913960400191505060405180910390fd5b6111da338683612aed565b506001949350505050565b6000805460ff16611232576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff191690556005546001600160a01b0316331461129b576040805162461bcd60e51b815260206004820152601760248201527f4552525f4d494e545f4e4f545f415554484f52495a4544000000000000000000604482015290519081900360640190fd5b600082116112e0576040805162461bcd60e51b815260206004820152600d60248201526c4552525f4d494e545f5a45524f60981b604482015290519081900360640190fd5b6112ea83836131b8565b6040805183815290516001600160a01b0385169130916000805160206139c98339815191529181900360200190a35060016000805460ff1916600117905592915050565b604051806040016040528060018152602001603160f81b81525081565b6006546001600160a01b031681565b6001600160a01b03166000908152600f602052604090205490565b6005546001600160a01b031681565b60096020526000908152604090205481565b60035442101590565b600c805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107cd5780601f106107a2576101008083540402835291602001916107cd565b6000805460ff16611447576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff191690556005546001600160a01b031633146114b0576040805162461bcd60e51b815260206004820152601760248201527f4552525f4255524e5f4e4f545f415554484f52495a4544000000000000000000604482015290519081900360640190fd5b600082116114f5576040805162461bcd60e51b815260206004820152600d60248201526c4552525f4255524e5f5a45524f60981b604482015290519081900360640190fd5b6114ff8383613306565b60408051838152905130916001600160a01b038616916000805160206139c98339815191529181900360200190a35060016000805460ff1916600117905592915050565b6010818154811061155357600080fd5b6000918252602090912001546001600160a01b0316905081565b336000908152600e602090815260408083206001600160a01b03861684529091528120548190819061159f908561316c565b909250905060008260048111156115b257fe5b146111cf5760405162461bcd60e51b81526004018080602001828103825260268152602001806137e76026913960400191505060405180910390fd5b60006107e2338484612fd8565b60025481565b60115461010090046001600160a01b03163314611655576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60115460405160009161010090046001600160a01b0316907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80908390a360118054610100600160a81b0319169055565b6000805460408051632d3caa7360e21b815230600482015233602482018190529151919261010090046001600160a01b03169163b4f2a9cc91604480820192602092909190829003018186803b1580156116fe57600080fd5b505afa158015611712573d6000803e3d6000fd5b505050506040513d602081101561172857600080fd5b5051611770576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff166117bc576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff191690556117ce6136e0565b6117d6611396565b1561181b576040805162461bcd60e51b815260206004820152601060248201526f11549497d093d39117d350551554915160821b604482015290519081900360640190fd5b60008411611862576040805162461bcd60e51b815260206004820152600f60248201526e4552525f424f52524f575f5a45524f60881b604482015290519081900360640190fd5b60048054604080516381a7bc9760e01b81523093810193909352516001600160a01b03909116916381a7bc97916024808301926020929190829003018186803b1580156118ae57600080fd5b505afa1580156118c2573d6000803e3d6000fd5b505050506040513d60208110156118d857600080fd5b5051611924576040805162461bcd60e51b815260206004820152601660248201527511549497d093d49493d5d7d393d517d0531313d5d15160521b604482015290519081900360640190fd5b611930600d5485613192565b60a083018190528282600481111561194457fe5b600481111561194f57fe5b905250600090508151600481111561196357fe5b146119ad576040805162461bcd60e51b815260206004820152601560248201527422a9292fa127a92927abafa6a0aa242fa2a92927a960591b604482015290519081900360640190fd5b600480546040805163d010b00f60e01b81523093810193909352516001600160a01b039091169163d010b00f916024808301926020929190829003018186803b1580156119f957600080fd5b505afa158015611a0d573d6000803e3d6000fd5b505050506040513d6020811015611a2357600080fd5b50516040820181905260a08201511115611a84576040805162461bcd60e51b815260206004820181905260248201527f4552525f424f52524f575f444542545f4345494c494e475f4f564552464c4f57604482015290519081900360640190fd5b6000546040805163bbd7edc560e01b815230600482015233602482015290516101009092046001600160a01b03169163bbd7edc591604480820192608092909190829003018186803b158015611ad957600080fd5b505afa158015611aed573d6000803e3d6000fd5b505050506040513d6080811015611b0357600080fd5b508051604090910151606083018190526020830191909152611b565760405162461bcd60e51b8152600401808060200182810382526021815260200180613a2d6021913960400191505060405180910390fd5b611b64816020015185613192565b60c0830181905282826004811115611b7857fe5b6004811115611b8357fe5b9052506000905081516004811115611b9757fe5b14611be1576040805162461bcd60e51b815260206004820152601560248201527422a9292fa127a92927abafa6a0aa242fa2a92927a960591b604482015290519081900360640190fd5b600054606082015160c08301516040805163d8e51dfb60e01b815230600482015233602482015260448101939093526064830191909152516101009092046001600160a01b03169163d8e51dfb91608480820192602092909190829003018186803b158015611c4f57600080fd5b505afa158015611c63573d6000803e3d6000fd5b505050506040513d6020811015611c7957600080fd5b50516080820152600480546040805163351da44160e21b81523093810193909352516001600160a01b039091169163d4769104916024808301926020929190829003018186803b158015611ccc57600080fd5b505afa158015611ce0573d6000803e3d6000fd5b505050506040513d6020811015611cf657600080fd5b505160e0820181905260808201511015611d415760405162461bcd60e51b81526004018080602001828103825260218152602001806137756021913960400191505060405180910390fd5b611d4b33856131b8565b604080518581529051339130916000805160206139c98339815191529181900360200190a36000805460c083015160408051630b9d2cc360e41b81523060048201523360248201526044810192909252516101009092046001600160a01b03169263b9d2cc30926064808401936020939083900390910190829087803b158015611dd457600080fd5b505af1158015611de8573d6000803e3d6000fd5b505050506040513d6020811015611dfe57600080fd5b5051611e51576040805162461bcd60e51b815260206004820152601e60248201527f4552525f424f52524f575f43414c4c5f5345545f5641554c545f444542540000604482015290519081900360640190fd5b60408051858152905133917fcbc04eca7e9da35cb1393a6135a199ca52e450d5e9251cbd99f7847d33a36750919081900360200190a26001925050506000805460ff19166001179055919050565b600181565b6001600160a01b038716611ee95760405162461bcd60e51b81526004018080602001828103825260238152602001806137526023913960400191505060405180910390fd5b6001600160a01b038616611f2e5760405162461bcd60e51b815260040180806020018281038252602581526020018061395d6025913960400191505060405180910390fd5b42841015611f83576040805162461bcd60e51b815260206004820152601860248201527f4552525f45524332305f5045524d49545f455850495245440000000000000000604482015290519081900360640190fd5b6001600160a01b0380881660008181526009602090815260408083208054600180820190925582517ffc77c2b9d30fe91687fd39abb7d16fcdfe1472d065740051ab8b13e4bf4a617f8186015280840196909652958c166060860152608085018b905260a085019590955260c08085018a90528151808603909101815260e08501825280519083012060085461190160f01b61010087015261010286015261012280860182905282518087039091018152610142860180845281519185019190912090859052610162860180845281905260ff8a166101828701526101a286018990526101c2860188905291519095919491926101e2808401939192601f1981019281900390910190855afa1580156120a0573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166120f25760405162461bcd60e51b815260040180806020018281038252602d8152602001806137ba602d913960400191505060405180910390fd5b896001600160a01b0316816001600160a01b0316146121425760405162461bcd60e51b81526004018080602001828103825260228152602001806139e96022913960400191505060405180910390fd5b61214d8a8a8a612aed565b50505050505050505050565b6001546001600160a01b031681565b60035481565b6001600160a01b039182166000908152600e6020908152604080832093909416825291909152205490565b60115461010090046001600160a01b031633146121ed576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b60115460ff1615612236576040805162461bcd60e51b815260206004820152600e60248201526d11549497d253925510531256915160921b604482015290519081900360640190fd5b8060005b818110156123d35783838281811061224e57fe5b905060200201356001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561229657600080fd5b505afa1580156122aa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156122d357600080fd5b8101908080516040519392919084600160201b8211156122f257600080fd5b90830190602082018581111561230757600080fd5b8251600160201b81118282018810171561232057600080fd5b82525081516020918201929091019080838360005b8381101561234d578181015183820152602001612335565b50505050905090810190601f16801561237a5780820380516001836020036101000a031916815260200191505b5060405250505050601084848381811061239057fe5b835460018181018655600095865260209586902090910180546001600160a01b0319166001600160a01b039690930294909401359490941617909155500161223a565b5060118054600160ff1990911617908190556040805160208082528082018690526101009093046001600160a01b0316927fd877543bef27da9036243421e623413c8fdd78d7d183cc93d8f3cddbd657a2ed928792879290918291908201908590850280828437600083820152604051601f909101601f19169092018290039550909350505050a2505050565b60115461010090046001600160a01b031633146124b4576040805162461bcd60e51b815260206004820152600d60248201526c22a9292fa727aa2fa0a226a4a760991b604482015290519081900360640190fd5b6001600160a01b03811661250f576040805162461bcd60e51b815260206004820152601a60248201527f4552525f5345545f41444d494e5f5a45524f5f41444452455353000000000000604482015290519081900360640190fd5b6011546040516001600160a01b0380841692610100900416907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf8090600090a3601180546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6000805460408051632d3caa7360e21b81523060048201526001600160a01b0386811660248301529151869361010090049092169163b4f2a9cc91604480820192602092909190829003018186803b1580156125d157600080fd5b505afa1580156125e5573d6000803e3d6000fd5b505050506040513d60208110156125fb57600080fd5b5051612643576040805162461bcd60e51b815260206004820152601260248201527122a9292fab20aaa62a2fa727aa2fa7a822a760711b604482015290519081900360640190fd5b60005460ff1661268f576040805162461bcd60e51b815260206004820152601260248201527111549497d4915153951490539517d0d0531360721b604482015290519081900360640190fd5b6000805460ff191690556126a1613726565b336001600160a01b03861614156126ff576040805162461bcd60e51b815260206004820152601960248201527f4552525f4c49515549444154455f424f52524f575f53454c4600000000000000604482015290519081900360640190fd5b60008411612754576040805162461bcd60e51b815260206004820152601960248201527f4552525f4c49515549444154455f424f52524f575f5a45524f00000000000000604482015290519081900360640190fd5b6004805460408051632ec8fffb60e21b81523093810193909352516001600160a01b039091169163bb23ffec916024808301926020929190829003018186803b1580156127a057600080fd5b505afa1580156127b4573d6000803e3d6000fd5b505050506040513d60208110156127ca57600080fd5b505161281d576040805162461bcd60e51b815260206004820181905260248201527f4552525f4c49515549444154455f424f52524f575f4e4f545f414c4c4f574544604482015290519081900360640190fd5b612825611396565b6129085760005460408051639ee91d1f60e01b81523060048201526001600160a01b038881166024830152915161010090930490911691639ee91d1f91604480820192602092909190829003018186803b15801561288257600080fd5b505afa158015612896573d6000803e3d6000fd5b505050506040513d60208110156128ac57600080fd5b5051151560608201819052612908576040805162461bcd60e51b815260206004820152601a60248201527f4552525f4143434f554e545f4e4f545f554e4445525741544552000000000000604482015290519081900360640190fd5b612913338686612bd9565b600080546040805163464b048560e01b81523060048201526024810188905290516101009092046001600160a01b03169163464b048591604480820192602092909190829003018186803b15801561296a57600080fd5b505afa15801561297e573d6000803e3d6000fd5b505050506040513d602081101561299457600080fd5b50516000805460408051630e496ef360e01b81523060048201523360248201526001600160a01b038b811660448301526064820186905291519495506101009092041692630e496ef392608480840193602093929083900390910190829087803b158015612a0157600080fd5b505af1158015612a15573d6000803e3d6000fd5b505050506040513d6020811015612a2b57600080fd5b5051612a685760405162461bcd60e51b815260040180806020018281038252602b8152602001806138a1602b913960400191505060405180910390fd5b604080518681526020810183905281516001600160a01b0389169233927f08b197b6ae66d18ee6fa20a826a84579a925b9e646a3bf19e96f59ed568c2688929081900390910190a3600193505050506000805460ff1916600117905592915050565b6004546001600160a01b031681565b60115461010090046001600160a01b031681565b6001600160a01b038316612b325760405162461bcd60e51b8152600401808060200182810382526023815260200180613a796023913960400191505060405180910390fd5b6001600160a01b038216612b775760405162461bcd60e51b815260040180806020018281038252602181526020018061382e6021913960400191505060405180910390fd5b6001600160a01b038084166000818152600e6020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b60008111612c26576040805162461bcd60e51b81526020600482015260156024820152744552525f52455041595f424f52524f575f5a45524f60581b604482015290519081900360640190fd5b600480546040805163e60f077360e01b81523093810193909352516001600160a01b039091169163e60f0773916024808301926020929190829003018186803b158015612c7257600080fd5b505afa158015612c86573d6000803e3d6000fd5b505050506040513d6020811015612c9c57600080fd5b5051612cef576040805162461bcd60e51b815260206004820152601c60248201527f4552525f52455041595f424f52524f575f4e4f545f414c4c4f57454400000000604482015290519081900360640190fd5b6000805460408051638a0695fd60e01b81523060048201526001600160a01b038681166024830152915161010090930490911691638a0695fd91604480820192602092909190829003018186803b158015612d4957600080fd5b505afa158015612d5d573d6000803e3d6000fd5b505050506040513d6020811015612d7357600080fd5b5051905081811015612db65760405162461bcd60e51b815260040180806020018281038252602281526020018061393b6022913960400191505060405180910390fd5b81612dc08561135a565b1015612dfd5760405162461bcd60e51b81526004018080602001828103825260258152602001806139166025913960400191505060405180910390fd5b612e078483613306565b60408051838152905130916001600160a01b038716916000805160206139c98339815191529181900360200190a3600080612e42838561316c565b90925090506000826004811115612e5557fe5b14612e5c57fe5b6000805460408051630b9d2cc360e41b81523060048201526001600160a01b0389811660248301526044820186905291516101009093049091169263b9d2cc30926064808401936020939083900390910190829087803b158015612ebf57600080fd5b505af1158015612ed3573d6000803e3d6000fd5b505050506040513d6020811015612ee957600080fd5b5051612f265760405162461bcd60e51b81526004018080602001828103825260248152602001806139826024913960400191505060405180910390fd5b846001600160a01b0316866001600160a01b03167fa9a154237a69922f8860321d1fec1624a5dbe8a8af89a3dd3d7a759f6c8080d88684604051808381526020018281526020019250505060405180910390a3505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612fd3908490613454565b505050565b6001600160a01b03831661301d5760405162461bcd60e51b815260040180806020018281038252602481526020018061384f6024913960400191505060405180910390fd5b6001600160a01b0382166130625760405162461bcd60e51b8152600401808060200182810382526022815260200180613a0b6022913960400191505060405180910390fd5b6001600160a01b0383166000908152600f602052604081205481908190613089908561316c565b9093509150600083600481111561309c57fe5b146130d85760405162461bcd60e51b815260040180806020018281038252602b815260200180613a4e602b913960400191505060405180910390fd5b6001600160a01b038087166000908152600f6020526040808220859055918716815220546131069085613192565b9093509050600083600481111561311957fe5b1461312057fe5b6001600160a01b038086166000818152600f60209081526040918290208590558151888152915192938a16926000805160206139c98339815191529281900390910190a3505050505050565b60008083831161318357506000905081830361318b565b506003905060005b9250929050565b6000808383018481106131aa5760009250905061318b565b60026000925092505061318b565b6001600160a01b0382166000908152600f6020526040812054819081906131df9085613192565b909350915060008360048111156131f257fe5b14613244576040805162461bcd60e51b815260206004820152601f60248201527f4552525f45524332305f4d494e545f42414c414e43455f4f564552464c4f5700604482015290519081900360640190fd5b6001600160a01b0385166000908152600f60205260409020829055600d5461326c9085613192565b9093509050600083600481111561327f57fe5b146132bb5760405162461bcd60e51b81526004018080602001828103825260248152602001806137966024913960400191505060405180910390fd5b600d8190556040805185815290516001600160a01b038716917f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885919081900360200190a25050505050565b6001600160a01b0382166000908152600f60205260408120548190819061332d908561316c565b9093509150600083600481111561334057fe5b14613392576040805162461bcd60e51b815260206004820181905260248201527f4552525f45524332305f4255524e5f42414c414e43455f554e444552464c4f57604482015290519081900360640190fd5b6001600160a01b0385166000908152600f60205260409020829055600d546133ba908561316c565b909350905060008360048111156133cd57fe5b146134095760405162461bcd60e51b81526004018080602001828103825260258152602001806138cc6025913960400191505060405180910390fd5b600d8190556040805185815290516001600160a01b038716917fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5919081900360200190a25050505050565b600061349683836040518060400160405280601d81526020017f4552525f534146455f45524332305f4c4f575f4c4556454c5f43414c4c000000815250613508565b805190915015612fd3578080602001905160208110156134b557600080fd5b5051612fd3576040805162461bcd60e51b815260206004820152601e60248201527f4552525f534146455f45524332305f45524332305f4f5045524154494f4e0000604482015290519081900360640190fd5b606061351c846001600160a01b03166136a4565b6135575760405162461bcd60e51b81526004018080602001828103825260238152602001806139a66023913960400191505060405180910390fd5b600080856001600160a01b0316856040518082805190602001908083835b602083106135945780518252601f199092019160209182019101613575565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146135f6576040519150601f19603f3d011682016040523d82523d6000602084013e6135fb565b606091505b5091509150811561360f579150610fce9050565b80511561361f5780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613669578181015183820152602001613651565b50505050905090810190601f1680156136965780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906136d857508115155b949350505050565b6040805161010081019091528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604080516080810190915280600081526020016000815260200160008152602001600015158152509056fe4552525f45524332305f5045524d49545f4f574e45525f5a45524f5f414444524553534552525f42454c4f575f434f4c4c41544552414c495a4154494f4e5f524154494f4552525f45524332305f4d494e545f544f54414c5f535550504c595f4f564552464c4f574552525f45524332305f5045524d49545f5245434f56455245445f4f574e45525f5a45524f5f414444524553534552525f45524332305f44454352454153455f414c4c4f57414e43455f554e444552464c4f574552525f5245434f5645525f4e4f4e5f5245434f56455241424c455f544f4b454e4552525f45524332305f415050524f56455f544f5f5a45524f5f414444524553534552525f45524332305f5452414e534645525f46524f4d5f5a45524f5f414444524553534552525f45524332305f5452414e534645525f46524f4d5f494e53554646494349454e545f414c4c4f57414e43454552525f4c49515549444154455f424f52524f575f43414c4c5f434c555443485f434f4c4c41544552414c4552525f45524332305f4255524e5f544f54414c5f535550504c595f554e444552464c4f574552525f45524332305f494e4352454153455f414c4c4f57414e43455f4f564552464c4f574552525f52455041595f424f52524f575f494e53554646494349454e545f42414c414e43454552525f52455041595f424f52524f575f494e53554646494349454e545f444542544552525f45524332305f5045524d49545f5350454e4445525f5a45524f5f414444524553534552525f52455041595f424f52524f575f43414c4c5f5345545f5641554c545f444542544552525f534146455f45524332305f43414c4c5f544f5f4e4f4e5f434f4e5452414354ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef4552525f45524332305f5045524d49545f494e56414c49445f5349474e41545552454552525f45524332305f5452414e534645525f544f5f5a45524f5f414444524553534552525f424f52524f575f4c4f434b45445f434f4c4c41544552414c5f5a45524f4552525f45524332305f5452414e534645525f53454e4445525f42414c414e43455f554e444552464c4f574552525f45524332305f415050524f56455f46524f4d5f5a45524f5f41444452455353a26469706673582212208cee194c7873c76d0f278e0c8b44232bda5b534513841a90b49f26680b23561664736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000060650d00000000000000000000000000ed4348fc8b1b634b3a0eadabfd32530046b89c6000000000000000000000000098e06ff5d4d43ca77772004a65022725d56a5a16000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000000000000000000000000000000000000000000164869666920555344432028323032322d30332d33312900000000000000000000000000000000000000000000000000000000000000000000000000000000000a685553444332324d617200000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name_ (string): Hifi USDC (2022-03-31)
Arg [1] : symbol_ (string): hUSDC22Mar
Arg [2] : expirationTime_ (uint256): 1617235200
Arg [3] : fintroller_ (address): 0xED4348fC8B1B634b3A0eadabFD32530046B89C60
Arg [4] : balanceSheet_ (address): 0x98e06ff5d4d43cA77772004A65022725D56a5a16
Arg [5] : underlying_ (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [6] : collateral_ (address): 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599
-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 0000000000000000000000000000000000000000000000000000000060650d00
Arg [3] : 000000000000000000000000ed4348fc8b1b634b3a0eadabfd32530046b89c60
Arg [4] : 00000000000000000000000098e06ff5d4d43ca77772004a65022725d56a5a16
Arg [5] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [6] : 0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000016
Arg [8] : 4869666920555344432028323032322d30332d33312900000000000000000000
Arg [9] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [10] : 685553444332324d617200000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
515:15959:23:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;416:18:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3133:173:10;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;3133:173:10;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;12888:206:23;;;;;;;;;;;;;;;;-1:-1:-1;12888:206:23;;:::i;652:26:18:-;;;:::i;:::-;;;;;;;;;;;;;;;;1357:40:25;;;:::i;2117:1196:15:-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;2117:1196:15;;;;;;;;:::i;:::-;;14360:473:23;;;;;;;;;;;;;;;;-1:-1:-1;14360:473:23;-1:-1:-1;;;;;14360:473:23;;:::i;408:41:25:-;;;:::i;:::-;;;;-1:-1:-1;;;;;408:41:25;;;;;;;;;;;;;;6316:522:10;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;6316:522:10;;;;;;;;;;;;;;;;;:::i;13677:270:23:-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;13677:270:23;;;;;;;;:::i;444:108:14:-;;;:::i;326:21:18:-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;277:31:14;;;:::i;4627:418:10:-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;4627:418:10;;;;;;;;:::i;11680:574:23:-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;11680:574:23;;;;;;;;:::i;736:36:14:-;;;:::i;1213:32:25:-;;;:::i;2219:124:10:-;;;;;;;;;;;;;;;;-1:-1:-1;2219:124:10;-1:-1:-1;;;;;2219:124:10;;:::i;1073:45:25:-;;;:::i;618:41:14:-;;;;;;;;;;;;;;;;-1:-1:-1;618:41:14;-1:-1:-1;;;;;618:41:14;;:::i;3754:114:23:-;;;:::i;551:20:18:-;;;:::i;7866:540:23:-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;7866:540:23;;;;;;;;:::i;227:44:17:-;;;;;;;;;;;;;;;;-1:-1:-1;227:44:17;;:::i;3809:429:10:-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;3809:429:10;;;;;;;;:::i;5419:179::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;5419:179:10;;;;;;;;:::i;687:40:25:-;;;:::i;1615:150:1:-;;;:::i;4975:2370:23:-;;;;;;;;;;;;;;;;-1:-1:-1;4975:2370:23;;:::i;1494:37:25:-;;;:::i;1868:1054:12:-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;1868:1054:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;543:32:25:-;;;:::i;820:29::-;;;:::i;1983:150:10:-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;1983:150:10;;;;;;;;;;:::i;934:625:15:-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;934:625:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;934:625:15;;;;;;;;;;-1:-1:-1;934:625:15;;-1:-1:-1;934:625:15;-1:-1:-1;934:625:15;:::i;1969:230:1:-;;;;;;;;;;;;;;;;-1:-1:-1;1969:230:1;-1:-1:-1;;;;;1969:230:1;;:::i;9512:1622:23:-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;9512:1622:23;;;;;;;;:::i;940:37:25:-;;;:::i;182:20:3:-;;;:::i;416:18:18:-;;;;;;;;;;;;;;;-1:-1:-1;;416:18:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3133:173:10:-;3218:4;3234:44;3250:10;3262:7;3271:6;3234:15;:44::i;:::-;-1:-1:-1;3295:4:10;3133:173;;;;:::o;12888:206:23:-;12994:4;872:12;;:39;;;-1:-1:-1;;;872:39:23;;897:4;872:39;;;;12960:10;872:39;;;;;;;;12960:10;;872:12;;;-1:-1:-1;;;;;872:12:23;;:24;;:39;;;;;;;;;;;;;;;:12;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;872:39:23;864:70;;;;;-1:-1:-1;;;864:70:23;;;;;;;;;;;;-1:-1:-1;;;864:70:23;;;;;;;;;;;;;;;1817:10:29::1;::::0;::::1;;1809:41;;;::::0;;-1:-1:-1;;;1809:41:29;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1809:41:29;;;;;;;;;;;;;::::1;;1942:5;1929:18:::0;;-1:-1:-1;;1929:18:29::1;::::0;;13010:56:23::2;13030:10;::::0;13054:11;13010:19:::2;:56::i;:::-;13083:4;13076:11;;-1:-1:-1::0;2126:10:29::1;:17:::0;;-1:-1:-1;;2126:17:29::1;2139:4;2126:17;::::0;;12888:206:23;;-1:-1:-1;12888:206:23:o;652:26:18:-;;;;:::o;1357:40:25:-;;;;:::o;2117:1196:15:-;931:5:1;;;;;-1:-1:-1;;;;;931:5:1;940:10;931:19;923:45;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;;;;2247:20:15::1;::::0;::::1;;:28;;:20:::0;:28:::1;2239:59;;;::::0;;-1:-1:-1;;;2239:59:15;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;2239:59:15;;;;;;;;;;;;;::::1;;2332:1;2316:13;:17;2308:46;;;::::0;;-1:-1:-1;;;2308:46:15;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;2308:46:15;;;;;;;;;;;;;::::1;;2365:23;2407:5;-1:-1:-1::0;;;;;2407:12:15::1;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;2407:14:15::1;::::0;::::1;;::::0;::::1;::::0;::::1;;;;;::::0;::::1;;;;;;;;;;;;;;;-1:-1:-1::0;;;2407:14:15::1;;;;;;::::0;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;;;2407:14:15;::::1;::::0;;::::1;::::0;-1:-1:-1;2407:14:15::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;2407:14:15;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;;::::1;;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;2391:32;;;;;;2365:58;;2433:14;2450:20;:27;;;;2433:44;;2882:9;2877:300;2901:6;2897:1;:10;2877:300;;;2982:20;3003:1;2982:23;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;2956:50:15;;::::1;2982:23:::0;::::1;2956:50;::::0;::::1;::::0;:143:::1;;;3065:20;3086:1;3065:23;;;;;;;;;::::0;;;::::1;::::0;;::::1;::::0;:32:::1;::::0;;-1:-1:-1;;;3065:32:15;;;;-1:-1:-1;;;;;3065:23:15;;::::1;::::0;:30:::1;::::0;:32:::1;::::0;;::::1;::::0;;;;;;:23;:32;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;3065:32:15::1;::::0;::::1;;::::0;::::1;::::0;::::1;;;;;::::0;::::1;;;;;;;;;;;;;;;-1:-1:-1::0;;;3065:32:15::1;;;;;;::::0;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;;;3065:32:15;::::1;::::0;;::::1;::::0;-1:-1:-1;3065:32:15::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;3065:32:15;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;;::::1;;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;3049:50;;;;;;3030:15;:69;;2956:143;2931:235;;;;-1:-1:-1::0;;;2931:235:15::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2914:1;2909:6;2877:300;;;-1:-1:-1::0;3233:5:15::1;::::0;3214:40:::1;::::0;-1:-1:-1;;;;;3214:18:15;;::::1;::::0;3233:5:::1;::::0;::::1;;3240:13:::0;3214:18:::1;:40::i;:::-;3278:5;::::0;3270:36:::1;::::0;;-1:-1:-1;;;;;3270:36:15;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;3278:5:::1;::::0;;::::1;;::::0;3270:36:::1;::::0;;;;;;;;;::::1;978:1:1;;2117:1196:15::0;;:::o;14360:473:23:-;931:5:1;;14456:4:23;;931:5:1;;;-1:-1:-1;;;;;931:5:1;940:10;931:19;923:45;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;;;;14544:13:23::1;-1:-1:-1::0;;;;;14544:26:23::1;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;14544:28:23;14536:70:::1;;;::::0;;-1:-1:-1;;;14536:70:23;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;14692:10;::::0;;-1:-1:-1;;;;;14712:26:23;;::::1;-1:-1:-1::0;;;;;;14712:26:23;::::1;::::0;::::1;::::0;;;14768:5:::1;::::0;14754:50:::1;::::0;;14692:10;;::::1;14754:50:::0;;;::::1;::::0;::::1;::::0;;;;;;14692:10:::1;14768:5:::0;;::::1;::::0;;::::1;::::0;14754:50:::1;::::0;;;;;;;::::1;-1:-1:-1::0;14822:4:23::1;::::0;14360:473;-1:-1:-1;;14360:473:23:o;408:41:25:-;;;;;;-1:-1:-1;;;;;408:41:25;;:::o;6316:522:10:-;6454:4;6470:43;6487:6;6495:9;6506:6;6470:16;:43::i;:::-;-1:-1:-1;;;;;6614:18:10;;6523:17;6614:18;;;:10;:18;;;;;;;;6633:10;6614:30;;;;;;;;6523:17;;6606:47;;6646:6;6606:7;:47::i;:::-;6580:73;;-1:-1:-1;6580:73:10;-1:-1:-1;6682:18:10;6671:7;:29;;;;;;;;;6663:88;;;;-1:-1:-1;;;6663:88:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6761:49;6777:6;6785:10;6797:12;6761:15;:49::i;:::-;6827:4;6820:11;;;;6316:522;;;;;;:::o;13677:270:23:-;13845:4;872:12;;:39;;;-1:-1:-1;;;872:39:23;;897:4;872:39;;;;-1:-1:-1;;;;;872:39:23;;;;;;;;;;;:12;;;;;;;:24;;:39;;;;;;;;;;;;;;;:12;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;872:39:23;864:70;;;;;-1:-1:-1;;;864:70:23;;;;;;;;;;;;-1:-1:-1;;;864:70:23;;;;;;;;;;;;;;;1817:10:29::1;::::0;::::1;;1809:41;;;::::0;;-1:-1:-1;;;1809:41:29;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1809:41:29;;;;;;;;;;;;;::::1;;1942:5;1929:18:::0;;-1:-1:-1;;1929:18:29::1;::::0;;13865:54:23::2;13885:10;13897:8:::0;13907:11;13865:19:::2;:54::i;:::-;13936:4;13929:11;;-1:-1:-1::0;2126:10:29::1;:17:::0;;-1:-1:-1;;2126:17:29::1;2139:4;2126:17;::::0;;13677:270:23;;-1:-1:-1;;13677:270:23:o;444:108:14:-;486:66;444:108;:::o;326:21:18:-;;;;;;:::o;277:31:14:-;;;;:::o;4627:418:10:-;4835:10;4717:4;4824:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;4824:31:10;;;;;;;;;;4717:4;;;;4816:52;;4857:10;4816:7;:52::i;:::-;4790:78;;-1:-1:-1;4790:78:10;-1:-1:-1;4897:18:10;4886:7;:29;;;;;;;;;4878:79;;;;-1:-1:-1;;;4878:79:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4967:50;4983:10;4995:7;5004:12;4967:15;:50::i;:::-;-1:-1:-1;5034:4:10;;4627:418;-1:-1:-1;;;;4627:418:10:o;11680:574:23:-;11775:4;1817:10:29;;;;1809:41;;;;;-1:-1:-1;;;1809:41:29;;;;;;;;;;;;-1:-1:-1;;;1809:41:29;;;;;;;;;;;;;;;1942:5;1929:18;;-1:-1:-1;;1929:18:29;;;11878:14:23::1;::::0;-1:-1:-1;;;;;11878:14:23::1;11856:10;:37;11848:73;;;::::0;;-1:-1:-1;;;11848:73:23;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;11995:1;11982:10;:14;11974:40;;;::::0;;-1:-1:-1;;;11974:40:23;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;11974:40:23;;;;;;;;;;;;;::::1;;12087:37;12100:11;12113:10;12087:12;:37::i;:::-;12177:48;::::0;;;;;;;-1:-1:-1;;;;;12177:48:23;::::1;::::0;12194:4:::1;::::0;-1:-1:-1;;;;;;;;;;;12177:48:23;;;;::::1;::::0;;::::1;-1:-1:-1::0;12243:4:23::1;2126:10:29::0;:17;;-1:-1:-1;;2126:17:29;2139:4;2126:17;;;11680:574:23;;-1:-1:-1;;11680:574:23:o;736:36:14:-;;;;;;;;;;;;;;-1:-1:-1;;;736:36:14;;;;:::o;1213:32:25:-;;;-1:-1:-1;;;;;1213:32:25;;:::o;2219:124:10:-;-1:-1:-1;;;;;2319:17:10;2293:7;2319:17;;;:8;:17;;;;;;;2219:124::o;1073:45:25:-;;;-1:-1:-1;;;;;1073:45:25;;:::o;618:41:14:-;;;;;;;;;;;;;:::o;3754:114:23:-;3847:14;;3828:15;:33;;3754:114;:::o;551:20:18:-;;;;;;;;;;;;;;;-1:-1:-1;;551:20:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7866:540:23;7956:4;1817:10:29;;;;1809:41;;;;;-1:-1:-1;;;1809:41:29;;;;;;;;;;;;-1:-1:-1;;;1809:41:29;;;;;;;;;;;;;;;1942:5;1929:18;;-1:-1:-1;;1929:18:29;;;8059:14:23::1;::::0;-1:-1:-1;;;;;8059:14:23::1;8037:10;:37;8029:73;;;::::0;;-1:-1:-1;;;8029:73:23;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;8176:1;8163:10;:14;8155:40;;;::::0;;-1:-1:-1;;;8155:40:23;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;8155:40:23;;;;;;;;;;;;;::::1;;8249:32;8262:6;8270:10;8249:12;:32::i;:::-;8334:43;::::0;;;;;;;8359:4:::1;::::0;-1:-1:-1;;;;;8334:43:23;::::1;::::0;-1:-1:-1;;;;;;;;;;;8334:43:23;;;;::::1;::::0;;::::1;-1:-1:-1::0;8395:4:23::1;2126:10:29::0;:17;;-1:-1:-1;;2126:17:29;2139:4;2126:17;;;7866:540:23;;-1:-1:-1;;7866:540:23:o;227:44:17:-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;227:44:17;;-1:-1:-1;227:44:17;:::o;3809:429:10:-;4022:10;3904:4;4011:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;4011:31:10;;;;;;;;;;3904:4;;;;4003:57;;4044:15;4003:7;:57::i;:::-;3977:83;;-1:-1:-1;3977:83:10;-1:-1:-1;4089:18:10;4078:7;:29;;;;;;;;;4070:80;;;;-1:-1:-1;;;4070:80:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5419:179;5507:4;5523:47;5540:10;5552:9;5563:6;5523:16;:47::i;687:40:25:-;;;;:::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;1706:5:::1;::::0;::::1;-1:-1:-1::0;;;;;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;4975:2370:23:-;5075:4;872:12;;:39;;;-1:-1:-1;;;872:39:23;;897:4;872:39;;;;5041:10;872:39;;;;;;;;5041:10;;872:12;;;-1:-1:-1;;;;;872:12:23;;:24;;:39;;;;;;;;;;;;;;;:12;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;872:39:23;864:70;;;;;-1:-1:-1;;;864:70:23;;;;;;;;;;;;-1:-1:-1;;;864:70:23;;;;;;;;;;;;;;;1817:10:29::1;::::0;::::1;;1809:41;;;::::0;;-1:-1:-1;;;1809:41:29;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1809:41:29;;;;;;;;;;;;;::::1;;1942:5;1929:18:::0;;-1:-1:-1;;1929:18:29::1;::::0;;5091:27:23::2;;:::i;:::-;5177:11;:9;:11::i;:::-;:20;5169:49;;;::::0;;-1:-1:-1;;;5169:49:23;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;5169:49:23;;;;;;;;;;;;;::::2;;5294:1;5279:12;:16;5271:44;;;::::0;;-1:-1:-1;;;5271:44:23;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;5271:44:23;;;;;;;;;;;;;::::2;;5407:10;::::0;;:33:::2;::::0;;-1:-1:-1;;;5407:33:23;;5435:4:::2;5407:33:::0;;::::2;::::0;;;;;-1:-1:-1;;;;;5407:10:23;;::::2;::::0;:27:::2;::::0;:33;;;;;::::2;::::0;;;;;;;;:10;:33;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;5407:33:23;5399:68:::2;;;::::0;;-1:-1:-1;;;5399:68:23;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;5399:68:23;;;;;;;;;;;;;::::2;;5561:34;5569:11;;5582:12;5561:7;:34::i;:::-;5529:28;::::0;::::2;5514:81:::0;;;5515:4;5514:81;::::2;::::0;::::2;;;;;;;;;;;;;;::::0;;-1:-1:-1;5629:18:23::2;::::0;-1:-1:-1;5613:12:23;;:34:::2;::::0;::::2;;;;;;;5605:68;;;::::0;;-1:-1:-1;;;5605:68:23;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;5605:68:23;;;;;;;;;;;;;::::2;;5702:10;::::0;;:35:::2;::::0;;-1:-1:-1;;;5702:35:23;;5732:4:::2;5702:35:::0;;::::2;::::0;;;;;-1:-1:-1;;;;;5702:10:23;;::::2;::::0;:29:::2;::::0;:35;;;;;::::2;::::0;;;;;;;;:10;:35;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;5702:35:23;5683:16:::2;::::0;::::2;:54:::0;;;5755:28:::2;::::0;::::2;::::0;:48:::2;;5747:93;;;::::0;;-1:-1:-1;;;5747:93:23;;::::2;;::::0;::::2;::::0;;;;;;;::::2;::::0;;;;;;;;;;;;;::::2;;5968:12;::::0;:39:::2;::::0;;-1:-1:-1;;;5968:39:23;;5990:4:::2;5968:39;::::0;::::2;::::0;5996:10:::2;5968:39:::0;;;;;;:12:::2;::::0;;::::2;-1:-1:-1::0;;;;;5968:12:23::2;::::0;:21:::2;::::0;:39;;;;;::::2;::::0;;;;;;;;;:12;:39;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;5968:39:23;;;;;;;;5941:21;::::2;5927:80:::0;;;5968:39:::2;5928:9:::0;::::2;5927:80:::0;;;;6017:71:::2;;;;-1:-1:-1::0;;;6017:71:23::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6129:32;6137:4;:9;;;6148:12;6129:7;:32::i;:::-;6113:12;::::0;::::2;6098:63:::0;;;6099:4;6098:63;::::2;::::0;::::2;;;;;;;;;;;;;;::::0;;-1:-1:-1;6195:18:23::2;::::0;-1:-1:-1;6179:12:23;;:34:::2;::::0;::::2;;;;;;;6171:68;;;::::0;;-1:-1:-1;;;6171:68:23;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;6171:68:23;;;;;;;;;;;;;::::2;;6387:12;::::0;6493:21:::2;::::0;::::2;::::0;6528:12:::2;::::0;::::2;::::0;6387:163:::2;::::0;;-1:-1:-1;;;6387:163:23;;6451:4:::2;6387:163;::::0;::::2;::::0;6469:10:::2;6387:163:::0;;;;;;;;;;;;;;;;;;;:12:::2;::::0;;::::2;-1:-1:-1::0;;;;;6387:12:23::2;::::0;:50:::2;::::0;:163;;;;;::::2;::::0;;;;;;;;;:12;:163;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;6387:163:23;6337:47:::2;::::0;::::2;:213:::0;6607:10:::2;::::0;;:46:::2;::::0;;-1:-1:-1;;;6607:46:23;;6648:4:::2;6607:46:::0;;::::2;::::0;;;;;-1:-1:-1;;;;;6607:10:23;;::::2;::::0;:40:::2;::::0;:46;;;;;6387:163:::2;::::0;6607:46;;;;;;;:10;:46;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;6607:46:23;6560:44:::2;::::0;::::2;:93:::0;;;6684:47:::2;::::0;::::2;::::0;:95:::2;;6663:175;;;;-1:-1:-1::0;;;6663:175:23::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6911:38;6924:10;6936:12;6911;:38::i;:::-;7002:49;::::0;;;;;;;7026:10:::2;::::0;7019:4:::2;::::0;-1:-1:-1;;;;;;;;;;;7002:49:23;;;;::::2;::::0;;::::2;7141:12;::::0;;7185::::2;::::0;::::2;::::0;7141:57:::2;::::0;;-1:-1:-1;;;7141:57:23;;7167:4:::2;7141:57;::::0;::::2;::::0;7173:10:::2;7141:57:::0;;;;;;;;;;;;:12:::2;::::0;;::::2;-1:-1:-1::0;;;;;7141:12:23::2;::::0;:25:::2;::::0;:57;;;;;::::2;::::0;;;;;;;;;;;:12;:57;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;7141:57:23;7133:100:::2;;;::::0;;-1:-1:-1;;;7133:100:23;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;7284:32;::::0;;;;;;;7291:10:::2;::::0;7284:32:::2;::::0;;;;;::::2;::::0;;::::2;7334:4;7327:11;;;-1:-1:-1::0;2126:10:29::1;:17:::0;;-1:-1:-1;;2126:17:29::1;2139:4;2126:17;::::0;;4975:2370:23;;-1:-1:-1;4975:2370:23:o;1494:37:25:-;1527:4;1494:37;:::o;1868:1054:12:-;-1:-1:-1;;;;;2079:22:12;;2071:70;;;;-1:-1:-1;;;2071:70:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2159:24:12;;2151:74;;;;-1:-1:-1;;;2151:74:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2255:15;2243:8;:27;;2235:64;;;;;-1:-1:-1;;;2235:64:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2501:13:12;;;2418:18;2501:13;;;:6;:13;;;;;;;;:15;;;;;;;;;2449:78;;486:66:14;2449:78:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2439:89;;;;;;2594:16;;-1:-1:-1;;;2565:58:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2555:69;;;;;;;;;2659:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2439:89;;2555:69;;2501:15;;2659:26;;;;;2501:13;;-1:-1:-1;;2659:26:12;;;;;;;;;;2501:15;2659:26;;;;;;;;;;;;;;;-1:-1:-1;;2659:26:12;;-1:-1:-1;;2659:26:12;;;-1:-1:-1;;;;;;;2704:31:12;;2696:89;;;;-1:-1:-1;;;2696:89:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2821:5;-1:-1:-1;;;;;2803:23:12;:14;-1:-1:-1;;;;;2803:23:12;;2795:70;;;;-1:-1:-1;;;2795:70:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2876:39;2892:5;2899:7;2908:6;2876:15;:39::i;:::-;1868:1054;;;;;;;;;;:::o;543:32:25:-;;;-1:-1:-1;;;;;543:32:25;;:::o;820:29::-;;;;:::o;1983:150:10:-;-1:-1:-1;;;;;2100:17:10;;;2074:7;2100:17;;;:10;:17;;;;;;;;:26;;;;;;;;;;;;;1983:150::o;934:625:15:-;931:5:1;;;;;-1:-1:-1;;;;;931:5:1;940:10;931:19;923:45;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;-1:-1:-1;;;923:45:1;;;;;;;;;;;;;;;1069:20:15::1;::::0;::::1;;:29;1061:56;;;::::0;;-1:-1:-1;;;1061:56:15;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1061:56:15;;;;;;;;;;;;;::::1;;1230:6:::0;1213:14:::1;1253:133;1277:6;1273:1;:10;1253:133;;;1307:6;;1314:1;1307:9;;;;;;;;;;;;;-1:-1:-1::0;;;;;1307:9:15::1;-1:-1:-1::0;;;;;1307:16:15::1;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;1307:18:15::1;::::0;::::1;;::::0;::::1;::::0;::::1;;;;;::::0;::::1;;;;;;;;;;;;;;;-1:-1:-1::0;;;1307:18:15::1;;;;;;::::0;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;;;1307:18:15;::::1;::::0;;::::1;::::0;-1:-1:-1;1307:18:15::1;;;;;::::0;::::1;;::::0;;-1:-1:-1;1307:18:15;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;;::::1;;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;1339:20;1365:6;;1372:1;1365:9;;;;;;;1339:36:::0;;::::1;::::0;;::::1;::::0;;-1:-1:-1;1339:36:15;;;1365:9:::1;1339:36:::0;;;;;;::::1;::::0;;-1:-1:-1;;;;;;1339:36:15::1;-1:-1:-1::0;;;;;1365:9:15;;;::::1;::::0;;;::::1;;::::0;;;::::1;1339:36;::::0;;;-1:-1:-1;1285:6:15::1;1253:133;;;-1:-1:-1::0;1471:20:15::1;:27:::0;;1494:4:::1;-1:-1:-1::0;;1471:27:15;;::::1;;::::0;;;;1514:38:::1;::::0;;::::1;::::0;;;;;::::1;::::0;;;1471:27:::1;1538:5:::0;;::::1;-1:-1:-1::0;;;;;1538:5:15::1;::::0;1514:38:::1;::::0;1545:6;;1514:38;;;;;;;;;;1545:6;;1514:38;::::1;::::0;1545:6;1514:38;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;-1:-1:-1::0;;1514:38:15::1;::::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;1514:38:15;;-1:-1:-1;;;;1514:38:15::1;978:1:1;934:625:15::0;;:::o;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;::::1;;::::0;2136:30:::1;::::0;;;::::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;9512:1622:23:-;9678:4;872:12;;:39;;;-1:-1:-1;;;872:39:23;;897:4;872:39;;;;-1:-1:-1;;;;;872:39:23;;;;;;;;;;;:12;;;;;;;:24;;:39;;;;;;;;;;;;;;;:12;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;872:39:23;864:70;;;;;-1:-1:-1;;;864:70:23;;;;;;;;;;;;-1:-1:-1;;;864:70:23;;;;;;;;;;;;;;;1817:10:29::1;::::0;::::1;;1809:41;;;::::0;;-1:-1:-1;;;1809:41:29;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1809:41:29;;;;;;;;;;;;;::::1;;1942:5;1929:18:::0;;-1:-1:-1;;1929:18:29::1;::::0;;9698:37:23::2;;:::i;:::-;9809:10;-1:-1:-1::0;;;;;9809:22:23;::::2;;;9801:60;;;::::0;;-1:-1:-1;;;9801:60:23;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;9936:1;9922:11;:15;9914:53;;;::::0;;-1:-1:-1;;;9914:53:23;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;10059:10;::::0;;:42:::2;::::0;;-1:-1:-1;;;10059:42:23;;10096:4:::2;10059:42:::0;;::::2;::::0;;;;;-1:-1:-1;;;;;10059:10:23;;::::2;::::0;:36:::2;::::0;:42;;;;;::::2;::::0;;;;;;;;:10;:42;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;10059:42:23;10051:87:::2;;;::::0;;-1:-1:-1;;;10051:87:23;;::::2;;::::0;::::2;::::0;;;;;;;::::2;::::0;;;;;;;;;;;;;::::2;;10255:11;:9;:11::i;:::-;10251:292;;10407:12;::::0;:48:::2;::::0;;-1:-1:-1;;;10407:48:23;;10440:4:::2;10407:48;::::0;::::2;::::0;-1:-1:-1;;;;;10407:48:23;;::::2;::::0;;;;;;:12:::2;::::0;;::::2;::::0;;::::2;::::0;:32:::2;::::0;:48;;;;;::::2;::::0;;;;;;;;;:12;:48;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;10407:48:23;10380:75:::2;;:24;::::0;::::2;:75:::0;;;10469:63:::2;;;::::0;;-1:-1:-1;;;10469:63:23;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;10618:54;10638:10;10650:8;10660:11;10618:19;:54::i;:::-;10734:34;10771:12:::0;;:55:::2;::::0;;-1:-1:-1;;;10771:55:23;;10808:4:::2;10771:55;::::0;::::2;::::0;;;;;;;;;:12:::2;::::0;;::::2;-1:-1:-1::0;;;;;10771:12:23::2;::::0;:36:::2;::::0;:55;;;;;::::2;::::0;;;;;;;;;:12;:55;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;10771:55:23;10857:12:::2;::::0;;:85:::2;::::0;;-1:-1:-1;;;10857:85:23;;10887:4:::2;10857:85;::::0;::::2;::::0;10893:10:::2;10857:85:::0;;;;-1:-1:-1;;;;;10857:85:23;;::::2;::::0;;;;;;;;;;;;10771:55;;-1:-1:-1;10857:12:23::2;::::0;;::::2;;::::0;:29:::2;::::0;:85;;;;;10771:55:::2;::::0;10857:85;;;;;;;;;;;:12;:85;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;10857:85:23;10836:175:::2;;;;-1:-1:-1::0;;;10836:175:23::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11027:78;::::0;;;;;::::2;::::0;::::2;::::0;;;;;-1:-1:-1;;;;;11027:78:23;::::2;::::0;11043:10:::2;::::0;11027:78:::2;::::0;;;;;;;;;::::2;11123:4;11116:11;;;;-1:-1:-1::0;2126:10:29::1;:17:::0;;-1:-1:-1;;2126:17:29::1;2139:4;2126:17;::::0;;9512:1622:23;;-1:-1:-1;;9512:1622:23:o;940:37:25:-;;;-1:-1:-1;;;;;940:37:25;;:::o;182:20:3:-;;;;;;-1:-1:-1;;;;;182:20:3;;:::o;7314:380:10:-;-1:-1:-1;;;;;7452:22:10;;7444:70;;;;-1:-1:-1;;;7444:70:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;7532:24:10;;7524:70;;;;-1:-1:-1;;;7524:70:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;7605:17:10;;;;;;;:10;:17;;;;;;;;:26;;;;;;;;;;;;;:35;;;7655:32;;;;;;;;;;;;;;;;;7314:380;;;:::o;14991:1481:23:-;15187:1;15173:11;:15;15165:49;;;;;-1:-1:-1;;;15165:49:23;;;;;;;;;;;;-1:-1:-1;;;15165:49:23;;;;;;;;;;;;;;;15306:10;;;:38;;;-1:-1:-1;;;15306:38:23;;15339:4;15306:38;;;;;;;;-1:-1:-1;;;;;15306:10:23;;;;:32;;:38;;;;;;;;;;;;;;:10;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15306:38:23;15298:79;;;;;-1:-1:-1;;;15298:79:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;15438:12;15453;;:41;;;-1:-1:-1;;;15453:41:23;;15479:4;15453:41;;;;-1:-1:-1;;;;;15453:41:23;;;;;;;;;:12;;;;;;;;:25;;:41;;;;;;;;;;;;;;;:12;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15453:41:23;;-1:-1:-1;15512:19:23;;;;15504:66;;;;-1:-1:-1;;;15504:66:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15662:11;15642:16;15652:5;15642:9;:16::i;:::-;:31;;15634:81;;;;-1:-1:-1;;;15634:81:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15768:32;15781:5;15788:11;15768:12;:32::i;:::-;15853:43;;;;;;;;15877:4;;-1:-1:-1;;;;;15853:43:23;;;-1:-1:-1;;;;;;;;;;;15853:43:23;;;;;;;;15961:17;15988:15;16034:26;16042:4;16048:11;16034:7;:26::i;:::-;16013:47;;-1:-1:-1;16013:47:23;-1:-1:-1;16163:18:23;16152:7;:29;;;;;;;;;16145:37;;;;16263:12;;;:50;;;-1:-1:-1;;;16263:50:23;;16289:4;16263:50;;;;-1:-1:-1;;;;;16263:50:23;;;;;;;;;;;;;;;:12;;;;;;;;:25;;:50;;;;;;;;;;;;;;;;;:12;:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16263:50:23;16255:99;;;;-1:-1:-1;;;16255:99:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16434:8;-1:-1:-1;;;;;16415:50:23;16427:5;-1:-1:-1;;;;;16415:50:23;;16444:11;16457:7;16415:50;;;;;;;;;;;;;;;;;;;;;;;;14991:1481;;;;;;:::o;857:214:30:-;1004:59;;;-1:-1:-1;;;;;1004:59:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1004:59:30;-1:-1:-1;;;1004:59:30;;;978:86;;997:5;;978:18;:86::i;:::-;857:214;;;:::o;10212:838:10:-;-1:-1:-1;;;;;10354:23:10;;10346:72;;;;-1:-1:-1;;;10346:72:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10436:26:10;;10428:73;;;;-1:-1:-1;;;10428:73:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10649:16:10;;10512:17;10649:16;;;:8;:16;;;;;;10512:17;;;;10641:33;;10667:6;10641:7;:33::i;:::-;10611:63;;-1:-1:-1;10611:63:10;-1:-1:-1;10703:18:10;10692:7;:29;;;;;;;;;10684:85;;;;-1:-1:-1;;;10684:85:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10779:16:10;;;;;;;:8;:16;;;;;;:35;;;10866:19;;;;;;;10858:36;;10887:6;10858:7;:36::i;:::-;10825:69;;-1:-1:-1;10825:69:10;-1:-1:-1;10922:18:10;10911:7;:29;;;;;;;;;10904:37;;;;-1:-1:-1;;;;;10951:19:10;;;;;;;:8;:19;;;;;;;;;:41;;;11008:35;;;;;;;10951:19;;11008:35;;;-1:-1:-1;;;;;;;;;;;11008:35:10;;;;;;;;;10212:838;;;;;;:::o;2701:239:7:-;2763:9;2774:7;2802:1;2797;:6;2793:141;;-1:-1:-1;2827:18:7;;-1:-1:-1;2847:5:7;;;2819:34;;2793:141;-1:-1:-1;2892:27:7;;-1:-1:-1;2921:1:7;2793:141;2701:239;;;;;:::o;587:262::-;649:9;;691:5;;;711:6;;;707:136;;741:18;;-1:-1:-1;761:1:7;-1:-1:-1;733:30:7;;707:136;802:26;830:1;794:38;;;;;;;9012:718:10;-1:-1:-1;;;;;9268:21:10;;9094:17;9268:21;;;:8;:21;;;;;;9094:17;;;;9260:42;;9291:10;9260:7;:42::i;:::-;9225:77;;-1:-1:-1;9225:77:10;-1:-1:-1;9331:18:10;9320:7;:29;;;;;;;;;9312:73;;;;;-1:-1:-1;;;9312:73:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;9395:21:10;;;;;;:8;:21;;;;;:45;;;9528:11;;9520:32;;9541:10;9520:7;:32::i;:::-;9492:60;;-1:-1:-1;9492:60:10;-1:-1:-1;9581:18:10;9570:7;:29;;;;;;;;;9562:78;;;;-1:-1:-1;;;9562:78:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9650:11;:28;;;9694:29;;;;;;;;-1:-1:-1;;;;;9694:29:10;;;;;;;;;;;;;9012:718;;;;;:::o;8006:683::-;-1:-1:-1;;;;;8247:16:10;;8083:17;8247:16;;;:8;:16;;;;;;8083:17;;;;8239:37;;8265:10;8239:7;:37::i;:::-;8209:67;;-1:-1:-1;8209:67:10;-1:-1:-1;8305:18:10;8294:7;:29;;;;;;;;;8286:74;;;;;-1:-1:-1;;;8286:74:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;8370:16:10;;;;;;:8;:16;;;;;:35;;;8491:11;;8483:32;;8504:10;8483:7;:32::i;:::-;8455:60;;-1:-1:-1;8455:60:10;-1:-1:-1;8544:18:10;8533:7;:29;;;;;;;;;8525:79;;;;-1:-1:-1;;;8525:79:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8614:11;:28;;;8658:24;;;;;;;;-1:-1:-1;;;;;8658:24:10;;;;;;;;;;;;;8006:683;;;;;:::o;1750:702:30:-;2175:23;2201:67;2222:5;2230:4;2201:67;;;;;;;;;;;;;;;;;:12;:67::i;:::-;2282:17;;2175:93;;-1:-1:-1;2282:21:30;2278:168;;2381:10;2370:30;;;;;;;;;;;;;;;-1:-1:-1;2370:30:30;2362:73;;;;;-1:-1:-1;;;2362:73:30;;;;;;;;;;;;;;;;;;;;;;;;;;;2458:961;2590:12;2622:19;:6;-1:-1:-1;;;;;2622:17:30;;:19::i;:::-;2614:67;;;;-1:-1:-1;;;2614:67:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2755:12;2769:23;2796:6;-1:-1:-1;;;;;2796:11:30;2808:4;2796:17;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2796:17:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2754:59;;;;2827:7;2823:590;;;2857:10;-1:-1:-1;2850:17:30;;-1:-1:-1;2850:17:30;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:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;911:634:0;971:4;1448:20;;1278:66;1495:23;;;;;;:42;;-1:-1:-1;1522:15:0;;;1495:42;1487:51;911:634;-1:-1:-1;;;;911:634:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://504e7960f16a46f68ab102d0a6c00cc3b4e3021515e5b688b79030739924e0a9
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ 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.