Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 23 from a total of 23 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| _transfer Owners... | 17665680 | 969 days ago | IN | 0 ETH | 0.00079857 | ||||
| Set Liquidation ... | 16350291 | 1154 days ago | IN | 0 ETH | 0.00086127 | ||||
| Set Liquidate Bo... | 16350284 | 1154 days ago | IN | 0 ETH | 0.00071885 | ||||
| Set Liquidate Bo... | 16350282 | 1154 days ago | IN | 0 ETH | 0.00071691 | ||||
| Set Liquidate Bo... | 16350281 | 1154 days ago | IN | 0 ETH | 0.00072549 | ||||
| Set Liquidate Bo... | 16350279 | 1154 days ago | IN | 0 ETH | 0.00073261 | ||||
| Set Deposit Unde... | 16350276 | 1154 days ago | IN | 0 ETH | 0.00067198 | ||||
| Set Deposit Unde... | 16350275 | 1154 days ago | IN | 0 ETH | 0.00068443 | ||||
| Set Deposit Unde... | 16350273 | 1154 days ago | IN | 0 ETH | 0.00069312 | ||||
| Set Deposit Unde... | 16350272 | 1154 days ago | IN | 0 ETH | 0.00067266 | ||||
| Set Deposit Coll... | 16350265 | 1154 days ago | IN | 0 ETH | 0.00077791 | ||||
| Set Collateral R... | 16350247 | 1154 days ago | IN | 0 ETH | 0.00081847 | ||||
| Set Collateral C... | 16350239 | 1154 days ago | IN | 0 ETH | 0.00112717 | ||||
| Set Debt Ceiling | 16350157 | 1154 days ago | IN | 0 ETH | 0.00162359 | ||||
| Set Debt Ceiling | 16350155 | 1154 days ago | IN | 0 ETH | 0.00173235 | ||||
| Set Debt Ceiling | 16350153 | 1154 days ago | IN | 0 ETH | 0.00170086 | ||||
| Set Debt Ceiling | 16350151 | 1154 days ago | IN | 0 ETH | 0.00174936 | ||||
| List Bond | 16350130 | 1154 days ago | IN | 0 ETH | 0.0013466 | ||||
| List Bond | 16350130 | 1154 days ago | IN | 0 ETH | 0.0013466 | ||||
| List Bond | 16350129 | 1154 days ago | IN | 0 ETH | 0.0013539 | ||||
| List Bond | 16350126 | 1154 days ago | IN | 0 ETH | 0.00155587 | ||||
| List Collateral | 16349479 | 1154 days ago | IN | 0 ETH | 0.00516133 | ||||
| _transfer Owners... | 16228720 | 1171 days ago | IN | 0 ETH | 0.00060025 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Fintroller
Compiler Version
v0.8.12+commit.f00d7308
Optimization Enabled:
Yes with 800 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.4;
import "@prb/contracts/access/Ownable.sol";
import "@prb/contracts/token/erc20/IErc20.sol";
import "./IFintroller.sol";
import "../h-token/IHToken.sol";
/// @notice Fintroller
/// @author Hifi
contract Fintroller is
IFintroller, // one dependency
Ownable // one dependency
{
/// PUBLIC STORAGE ///
/// @inheritdoc IFintroller
uint256 public override maxBonds;
/// @inheritdoc IFintroller
uint256 public override maxCollaterals;
/// INTERNAL STORAGE ///
/// @dev The threshold below which the collateral ratio cannot be set, equivalent to 100%.
uint256 internal constant COLLATERAL_RATIO_LOWER_BOUND = 1.0e18;
/// @dev The threshold above which the collateral ratio cannot be set, equivalent to 10,000%.
uint256 internal constant COLLATERAL_RATIO_UPPER_BOUND = 1.0e20;
/// @dev The default collateral ratio set when a new bond is listed, equivalent to 150%.
uint256 internal constant DEFAULT_COLLATERAL_RATIO = 1.5e18;
/// @dev The default liquidation incentive set when a new bond is listed, equivalent to 110%.
uint256 internal constant DEFAULT_LIQUIDATION_INCENTIVE = 1.1e18;
/// @dev The default maximum number of bond markets a single account can enter.
uint256 internal constant DEFAULT_MAX_BONDS = 10;
/// @dev The default maximum number of collaterals a single account can deposit.
uint256 internal constant DEFAULT_MAX_COLLATERALS = 10;
/// @dev The threshold below which the liquidation incentive cannot be set, equivalent to 100%.
uint256 internal constant LIQUIDATION_INCENTIVE_LOWER_BOUND = 1.0e18;
/// @dev The threshold above which the liquidation incentive cannot be set, equivalent to 150%.
uint256 internal constant LIQUIDATION_INCENTIVE_UPPER_BOUND = 1.5e18;
/// @notice Maps hTokens to Bond structs.
mapping(IHToken => Bond) internal bonds;
/// @notice Maps IErc20s to Collateral structs.
mapping(IErc20 => Collateral) internal collaterals;
/// CONSTRUCTOR ///
constructor() Ownable() {
// Set the max bonds limit.
maxBonds = DEFAULT_MAX_BONDS;
// Set the max collaterals limit
maxCollaterals = DEFAULT_MAX_COLLATERALS;
}
/// PUBLIC CONSTANT FUNCTIONS ///
/// @inheritdoc IFintroller
function getBond(IHToken hToken) external view override returns (Bond memory) {
return bonds[hToken];
}
/// @inheritdoc IFintroller
function getBorrowAllowed(IHToken bond) external view override returns (bool) {
if (!bonds[bond].isListed) {
revert Fintroller__BondNotListed(bond);
}
return bonds[bond].isBorrowAllowed;
}
/// @inheritdoc IFintroller
function getCollateral(IErc20 collateral) external view override returns (Collateral memory) {
return collaterals[collateral];
}
/// @inheritdoc IFintroller
function getCollateralCeiling(IErc20 collateral) external view override returns (uint256) {
return collaterals[collateral].ceiling;
}
/// @inheritdoc IFintroller
function getCollateralRatio(IErc20 collateral) external view override returns (uint256) {
return collaterals[collateral].ratio;
}
/// @inheritdoc IFintroller
function getDebtCeiling(IHToken bond) external view override returns (uint256) {
return bonds[bond].debtCeiling;
}
/// @inheritdoc IFintroller
function getDepositCollateralAllowed(IErc20 collateral) external view override returns (bool) {
if (!collaterals[collateral].isListed) {
revert Fintroller__CollateralNotListed(collateral);
}
return collaterals[collateral].isDepositCollateralAllowed;
}
/// @inheritdoc IFintroller
function getDepositUnderlyingAllowed(IHToken bond) external view override returns (bool) {
if (!bonds[bond].isListed) {
revert Fintroller__BondNotListed(bond);
}
return bonds[bond].isDepositUnderlyingAllowed;
}
/// @inheritdoc IFintroller
function getLiquidationIncentive(IErc20 collateral) external view override returns (uint256) {
return collaterals[collateral].liquidationIncentive;
}
/// @inheritdoc IFintroller
function getLiquidateBorrowAllowed(IHToken bond) external view override returns (bool) {
if (!bonds[bond].isListed) {
revert Fintroller__BondNotListed(bond);
}
return bonds[bond].isLiquidateBorrowAllowed;
}
/// @inheritdoc IFintroller
function getRepayBorrowAllowed(IHToken bond) external view override returns (bool) {
if (!bonds[bond].isListed) {
revert Fintroller__BondNotListed(bond);
}
return bonds[bond].isRepayBorrowAllowed;
}
/// @inheritdoc IFintroller
function isBondListed(IHToken bond) external view override returns (bool) {
return bonds[bond].isListed;
}
/// @notice Checks if the collateral is listed.
/// @param collateral The collateral to make the check against.
/// @return bool true = listed, otherwise not.
function isCollateralListed(IErc20 collateral) external view override returns (bool) {
return collaterals[collateral].isListed;
}
/// PUBLIC NON-CONSTANT FUNCTIONS ///
/// @inheritdoc IFintroller
function listBond(IHToken bond) external override onlyOwner {
bonds[bond] = Bond({
debtCeiling: 0,
isBorrowAllowed: true,
isDepositUnderlyingAllowed: true,
isLiquidateBorrowAllowed: true,
isListed: true,
isRepayBorrowAllowed: true
});
emit ListBond(owner, bond);
}
/// @inheritdoc IFintroller
function listCollateral(IErc20 collateral) external override onlyOwner {
// Checks: decimals are between the expected bounds.
uint256 decimals = collateral.decimals();
if (decimals == 0) {
revert Fintroller__CollateralDecimalsZero();
}
if (decimals > 18) {
revert Fintroller__CollateralDecimalsOverflow(decimals);
}
// Effects: update storage.
collaterals[collateral] = Collateral({
ceiling: 0,
isDepositCollateralAllowed: true,
isListed: true,
liquidationIncentive: DEFAULT_LIQUIDATION_INCENTIVE,
ratio: DEFAULT_COLLATERAL_RATIO
});
emit ListCollateral(owner, collateral);
}
/// @inheritdoc IFintroller
function setBorrowAllowed(IHToken bond, bool state) external override onlyOwner {
if (!bonds[bond].isListed) {
revert Fintroller__BondNotListed(bond);
}
if (state && !bonds[bond].isLiquidateBorrowAllowed) {
revert Fintroller__BondBorrowAllowedWithLiquidateBorrowDisallowed();
}
bonds[bond].isBorrowAllowed = state;
emit SetBorrowAllowed(owner, bond, state);
}
/// @inheritdoc IFintroller
function setCollateralCeiling(IHToken collateral, uint256 newCollateralCeiling) external override onlyOwner {
// Checks: collateral is listed.
if (!collaterals[collateral].isListed) {
revert Fintroller__CollateralNotListed(collateral);
}
// Effects: update storage.
uint256 oldCollateralCeiling = collaterals[collateral].ceiling;
collaterals[collateral].ceiling = newCollateralCeiling;
emit SetCollateralCeiling(owner, collateral, oldCollateralCeiling, newCollateralCeiling);
}
/// @inheritdoc IFintroller
function setCollateralRatio(IErc20 collateral, uint256 newCollateralRatio) external override onlyOwner {
// Checks: collateral is listed.
if (!collaterals[collateral].isListed) {
revert Fintroller__CollateralNotListed(collateral);
}
// Checks: new collateral ratio is within the accepted bounds.
if (newCollateralRatio > COLLATERAL_RATIO_UPPER_BOUND) {
revert Fintroller__CollateralRatioOverflow(newCollateralRatio);
}
if (newCollateralRatio < COLLATERAL_RATIO_LOWER_BOUND) {
revert Fintroller__CollateralRatioUnderflow(newCollateralRatio);
}
if (newCollateralRatio < collaterals[collateral].liquidationIncentive) {
revert Fintroller__CollateralRatioBelowLiquidationIncentive(newCollateralRatio);
}
// Effects: update storage.
uint256 oldCollateralRatio = collaterals[collateral].ratio;
collaterals[collateral].ratio = newCollateralRatio;
emit SetCollateralRatio(owner, collateral, oldCollateralRatio, newCollateralRatio);
}
/// @inheritdoc IFintroller
function setDebtCeiling(IHToken bond, uint256 newDebtCeiling) external override onlyOwner {
// Checks: bond is listed.
if (!bonds[bond].isListed) {
revert Fintroller__BondNotListed(bond);
}
// Checks: above total supply of hTokens.
uint256 totalSupply = bond.totalSupply();
if (newDebtCeiling < totalSupply) {
revert Fintroller__DebtCeilingUnderflow(newDebtCeiling, totalSupply);
}
// Effects: update storage.
uint256 oldDebtCeiling = bonds[bond].debtCeiling;
bonds[bond].debtCeiling = newDebtCeiling;
emit SetDebtCeiling(owner, bond, oldDebtCeiling, newDebtCeiling);
}
/// @inheritdoc IFintroller
function setDepositCollateralAllowed(IErc20 collateral, bool state) external override onlyOwner {
if (!collaterals[collateral].isListed) {
revert Fintroller__CollateralNotListed(collateral);
}
collaterals[collateral].isDepositCollateralAllowed = state;
emit SetDepositCollateralAllowed(owner, collateral, state);
}
/// @inheritdoc IFintroller
function setDepositUnderlyingAllowed(IHToken bond, bool state) external override onlyOwner {
if (!bonds[bond].isListed) {
revert Fintroller__BondNotListed(bond);
}
bonds[bond].isDepositUnderlyingAllowed = state;
emit SetDepositUnderlyingAllowed(owner, bond, state);
}
/// @inheritdoc IFintroller
function setLiquidateBorrowAllowed(IHToken bond, bool state) external override onlyOwner {
if (!bonds[bond].isListed) {
revert Fintroller__BondNotListed(bond);
}
if (state && !bonds[bond].isRepayBorrowAllowed) {
revert Fintroller__BondLiquidateBorrowAllowedWithRepayBorrowDisallowed();
}
if (!state && bonds[bond].isBorrowAllowed) {
revert Fintroller__BondLiquidateBorrowDisallowedWithBorrowAllowed();
}
bonds[bond].isLiquidateBorrowAllowed = state;
emit SetLiquidateBorrowAllowed(owner, bond, state);
}
/// @inheritdoc IFintroller
function setLiquidationIncentive(IErc20 collateral, uint256 newLiquidationIncentive) external override onlyOwner {
// Checks: collateral is listed.
if (!collaterals[collateral].isListed) {
revert Fintroller__CollateralNotListed(collateral);
}
// Checks: new collateral ratio is within the accepted bounds.
if (newLiquidationIncentive > LIQUIDATION_INCENTIVE_UPPER_BOUND) {
revert Fintroller__LiquidationIncentiveOverflow(newLiquidationIncentive);
}
if (newLiquidationIncentive < LIQUIDATION_INCENTIVE_LOWER_BOUND) {
revert Fintroller__LiquidationIncentiveUnderflow(newLiquidationIncentive);
}
if (newLiquidationIncentive > collaterals[collateral].ratio) {
revert Fintroller__LiquidationIncentiveAboveCollateralRatio(newLiquidationIncentive);
}
// Effects: update storage.
uint256 oldLiquidationIncentive = collaterals[collateral].liquidationIncentive;
collaterals[collateral].liquidationIncentive = newLiquidationIncentive;
emit SetLiquidationIncentive(owner, collateral, oldLiquidationIncentive, newLiquidationIncentive);
}
/// @inheritdoc IFintroller
function setMaxBonds(uint256 newMaxBonds) external override onlyOwner {
uint256 oldMaxBonds = maxBonds;
maxBonds = newMaxBonds;
emit SetMaxBonds(owner, oldMaxBonds, newMaxBonds);
}
/// @inheritdoc IFintroller
function setMaxCollaterals(uint256 newMaxCollaterals) external override onlyOwner {
uint256 oldMaxCollaterals = maxCollaterals;
maxCollaterals = newMaxCollaterals;
emit SetMaxCollaterals(owner, oldMaxCollaterals, newMaxCollaterals);
}
/// @inheritdoc IFintroller
function setRepayBorrowAllowed(IHToken bond, bool state) external override onlyOwner {
if (!bonds[bond].isListed) {
revert Fintroller__BondNotListed(bond);
}
if (!state && bonds[bond].isLiquidateBorrowAllowed) {
revert Fintroller__BondRepayBorrowDisallowedWithLiquidateBorrowAllowed();
}
bonds[bond].isRepayBorrowAllowed = state;
emit SetRepayBorrowAllowed(owner, bond, state);
}
}// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.4;
import "./IOwnable.sol";
/// @notice Emitted when the caller is not the owner.
error Ownable__NotOwner(address owner, address caller);
/// @notice Emitted when setting the owner to the zero address.
error Ownable__OwnerZeroAddress();
/// @title Ownable
/// @author Paul Razvan Berg
contract Ownable is IOwnable {
/// PUBLIC STORAGE ///
/// @inheritdoc IOwnable
address public override owner;
/// MODIFIERS ///
/// @notice Throws if called by any account other than the owner.
modifier onlyOwner() {
if (owner != msg.sender) {
revert Ownable__NotOwner(owner, msg.sender);
}
_;
}
/// CONSTRUCTOR ///
/// @notice Initializes the contract setting the deployer as the initial owner.
constructor() {
address msgSender = msg.sender;
owner = msgSender;
emit TransferOwnership(address(0), msgSender);
}
/// PUBLIC NON-CONSTANT FUNCTIONS ///
/// @inheritdoc IOwnable
function _renounceOwnership() public virtual override onlyOwner {
emit TransferOwnership(owner, address(0));
owner = address(0);
}
/// @inheritdoc IOwnable
function _transferOwnership(address newOwner) public virtual override onlyOwner {
if (newOwner == address(0)) {
revert Ownable__OwnerZeroAddress();
}
emit TransferOwnership(owner, newOwner);
owner = newOwner;
}
}// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.4;
/// @title IErc20
/// @author Paul Razvan Berg
/// @notice Implementation for the Erc20 standard.
///
/// 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 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.
///
/// @dev Forked from OpenZeppelin
/// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/token/ERC20/ERC20.sol
interface IErc20 {
/// EVENTS ///
/// @notice Emitted when an approval happens.
/// @param owner The address of the owner of the tokens.
/// @param spender The address of the spender.
/// @param amount The maximum amount that can be spent.
event Approval(address indexed owner, address indexed spender, uint256 amount);
/// @notice Emitted when a transfer happens.
/// @param from The account sending the tokens.
/// @param to The account receiving the tokens.
/// @param amount The amount of tokens transferred.
event Transfer(address indexed from, address indexed to, uint256 amount);
/// 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.
///
/// @dev This value changes when {approve} or {transferFrom} are called.
function allowance(address owner, address spender) external view returns (uint256);
/// @notice Returns the amount of tokens owned by `account`.
function balanceOf(address account) external view returns (uint256);
/// @notice Returns the number of decimals used to get its user representation.
function decimals() external view returns (uint8);
/// @notice Returns the name of the token.
function name() external view returns (string memory);
/// @notice Returns the symbol of the token, usually a shorter version of the name.
function symbol() external view returns (string memory);
/// @notice Returns the amount of tokens in existence.
function totalSupply() external view returns (uint256);
/// NON-CONSTANT FUNCTIONS ///
/// @notice Sets `amount` as the allowance of `spender` over the caller's tokens.
///
/// @dev Emits an {Approval} event.
///
/// 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
///
/// Requirements:
///
/// - `spender` cannot be the zero address.
///
/// @return a boolean value indicating whether the operation succeeded.
function approve(address spender, uint256 amount) external returns (bool);
/// @notice Atomically decreases the allowance granted to `spender` by the caller.
///
/// @dev Emits an {Approval} event indicating the updated allowance.
///
/// This is an alternative to {approve} that can be used as a mitigation for problems described
/// in {Erc20Interface-approve}.
///
/// Requirements:
///
/// - `spender` cannot be the zero address.
/// - `spender` must have allowance for the caller of at least `subtractedAmount`.
function decreaseAllowance(address spender, uint256 subtractedAmount) external returns (bool);
/// @notice Atomically increases the allowance granted to `spender` by the caller.
///
/// @dev Emits an {Approval} event indicating the updated allowance.
///
/// This is an alternative to {approve} that can be used as a mitigation for the problems described above.
///
/// Requirements:
///
/// - `spender` cannot be the zero address.
function increaseAllowance(address spender, uint256 addedAmount) external returns (bool);
/// @notice Moves `amount` tokens from the caller's account to `recipient`.
///
/// @dev Emits a {Transfer} event.
///
/// Requirements:
///
/// - `recipient` cannot be the zero address.
/// - The caller must have a balance of at least `amount`.
///
/// @return a boolean value indicating whether the operation succeeded.
function transfer(address recipient, uint256 amount) external returns (bool);
/// @notice 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 and an {Approval} event indicating the updated allowance. This is
/// not required by the Erc. See the note at the beginning of {Erc20}.
///
/// Requirements:
///
/// - `sender` and `recipient` cannot be the zero address.
/// - `sender` must have a balance of at least `amount`.
/// - The caller must have approed `sender` to spent at least `amount` tokens.
///
/// @return a boolean value indicating whether the operation succeeded.
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;
import "@prb/contracts/token/erc20/IErc20.sol";
import "@prb/contracts/access/IOwnable.sol";
import "../h-token/IHToken.sol";
/// @notice IFintroller
/// @author Hifi
/// @notice Controls the financial permissions and risk parameters for the Hifi protocol.
interface IFintroller is IOwnable {
/// CUSTOM ERRORS ///
/// @notice Emitted when interacting with a bond that is not listed.
error Fintroller__BondNotListed(IHToken bond);
/// @notice Emitted when allowing borrow for a bond when liquidate borrow is disallowed.
error Fintroller__BondBorrowAllowedWithLiquidateBorrowDisallowed();
/// @notice Emitted when allowing liquidate borrow for a bond when repay borrow is disallowed.
error Fintroller__BondLiquidateBorrowAllowedWithRepayBorrowDisallowed();
/// @notice Emitted when disallowing liquidate borrow for a bond when borrow is allowed.
error Fintroller__BondLiquidateBorrowDisallowedWithBorrowAllowed();
/// @notice Emitted when disallowing repay borrow for a bond when liquidate borrow is allowed.
error Fintroller__BondRepayBorrowDisallowedWithLiquidateBorrowAllowed();
/// @notice Emitted when listing a collateral that has more than 18 decimals.
error Fintroller__CollateralDecimalsOverflow(uint256 decimals);
/// @notice Emitted when listing a collateral that has zero decimals.
error Fintroller__CollateralDecimalsZero();
/// @notice Emitted when interacting with a collateral that is not listed.
error Fintroller__CollateralNotListed(IErc20 collateral);
/// @notice Emitted when setting a new collateral ratio that is below the liquidation incentive
error Fintroller__CollateralRatioBelowLiquidationIncentive(uint256 newCollateralRatio);
/// @notice Emitted when setting a new collateral ratio that is above the upper bound.
error Fintroller__CollateralRatioOverflow(uint256 newCollateralRatio);
/// @notice Emitted when setting a new collateral ratio that is below the lower bound.
error Fintroller__CollateralRatioUnderflow(uint256 newCollateralRatio);
/// @notice Emitted when setting a new debt ceiling that is below the total supply of hTokens.
error Fintroller__DebtCeilingUnderflow(uint256 newDebtCeiling, uint256 totalSupply);
/// @notice Emitted when setting a new liquidation incentive that is higher than the collateral ratio.
error Fintroller__LiquidationIncentiveAboveCollateralRatio(uint256 newLiquidationIncentive);
/// @notice Emitted when setting a new liquidation incentive that is above the upper bound.
error Fintroller__LiquidationIncentiveOverflow(uint256 newLiquidationIncentive);
/// @notice Emitted when setting a new liquidation incentive that is below the lower bound.
error Fintroller__LiquidationIncentiveUnderflow(uint256 newLiquidationIncentive);
/// EVENTS ///
/// @notice Emitted when a new bond is listed.
/// @param owner The address of the contract owner.
/// @param bond The newly listed bond.
event ListBond(address indexed owner, IHToken indexed bond);
/// @notice Emitted when a new collateral is listed.
/// @param owner The address of the contract owner.
/// @param collateral The newly listed collateral.
event ListCollateral(address indexed owner, IErc20 indexed collateral);
/// @notice Emitted when the borrow permission is updated.
/// @param owner The address of the contract owner.
/// @param bond The related HToken.
/// @param state True if borrowing is allowed.
event SetBorrowAllowed(address indexed owner, IHToken indexed bond, bool state);
/// @notice Emitted when the collateral ceiling is updated.
/// @param owner The address of the contract owner.
/// @param collateral The related collateral.
/// @param oldCollateralCeiling The old collateral ceiling.
/// @param newCollateralCeiling The new collateral ceiling.
event SetCollateralCeiling(
address indexed owner,
IErc20 indexed collateral,
uint256 oldCollateralCeiling,
uint256 newCollateralCeiling
);
/// @notice Emitted when the collateral ratio is updated.
/// @param owner The address of the contract owner.
/// @param collateral The related HToken.
/// @param oldCollateralRatio The old collateral ratio.
/// @param newCollateralRatio the new collateral ratio.
event SetCollateralRatio(
address indexed owner,
IErc20 indexed collateral,
uint256 oldCollateralRatio,
uint256 newCollateralRatio
);
/// @notice Emitted when the debt ceiling for a bond is updated.
/// @param owner The address of the contract owner.
/// @param bond The related HToken.
/// @param oldDebtCeiling The old debt ceiling.
/// @param newDebtCeiling The new debt ceiling.
event SetDebtCeiling(address indexed owner, IHToken indexed bond, uint256 oldDebtCeiling, uint256 newDebtCeiling);
/// @notice Emitted when the deposit collateral permission is updated.
/// @param owner The address of the contract owner.
/// @param state True if depositing collateral is allowed.
event SetDepositCollateralAllowed(address indexed owner, IErc20 indexed collateral, bool state);
/// @notice Emitted when the deposit underlying permission is set.
/// @param owner The address of the contract owner.
/// @param bond The related HToken.
/// @param state True if deposit underlying is allowed.
event SetDepositUnderlyingAllowed(address indexed owner, IHToken indexed bond, bool state);
/// @notice Emitted when the liquidate borrow permission is updated.
/// @param owner The address of the contract owner.
/// @param bond The related HToken.
/// @param state True if liquidating borrow is allowed.
event SetLiquidateBorrowAllowed(address indexed owner, IHToken indexed bond, bool state);
/// @notice Emitted when the collateral liquidation incentive is set.
/// @param owner The address of the contract owner.
/// @param collateral The related collateral.
/// @param oldLiquidationIncentive The old liquidation incentive.
/// @param newLiquidationIncentive The new liquidation incentive.
event SetLiquidationIncentive(
address indexed owner,
IErc20 collateral,
uint256 oldLiquidationIncentive,
uint256 newLiquidationIncentive
);
/// @notice Emitted when a new max bonds value is set.
/// @param owner The address indexed owner.
/// @param oldMaxBonds The address of the old max bonds value.
/// @param newMaxBonds The address of the new max bonds value.
event SetMaxBonds(address indexed owner, uint256 oldMaxBonds, uint256 newMaxBonds);
/// @notice Emitted when a new max collaterals value is set.
/// @param owner The address indexed owner.
/// @param oldMaxCollaterals The address of the old max collaterals value.
/// @param newMaxCollaterals The address of the new max collaterals value.
event SetMaxCollaterals(address indexed owner, uint256 oldMaxCollaterals, uint256 newMaxCollaterals);
/// @notice Emitted when the repay borrow permission is updated.
/// @param owner The address of the contract owner.
/// @param bond The related HToken.
/// @param state True if repaying borrow is allowed.
event SetRepayBorrowAllowed(address indexed owner, IHToken indexed bond, bool state);
/// STRUCTS ///
struct Bond {
uint256 debtCeiling;
bool isBorrowAllowed;
bool isDepositUnderlyingAllowed;
bool isLiquidateBorrowAllowed;
bool isListed;
bool isRepayBorrowAllowed;
}
struct Collateral {
uint256 ceiling;
uint256 ratio;
uint256 liquidationIncentive;
bool isDepositCollateralAllowed;
bool isListed;
}
/// CONSTANT FUNCTIONS ///
/// @notice Returns the Bond struct instance associated to the given address.
/// @dev It is not an error to provide an invalid address.
/// @param bond The address of the bond contract.
/// @return The bond object.
function getBond(IHToken bond) external view returns (Bond memory);
/// @notice Checks if the account should be allowed to borrow hTokens.
/// @dev The bond must be listed.
/// @param bond The bond to make the check against.
/// @return bool true = allowed, false = not allowed.
function getBorrowAllowed(IHToken bond) external view returns (bool);
/// @notice Returns the Collateral struct instance associated to the given address.
/// @dev It is not an error to provide an invalid address.
/// @param collateral The address of the collateral contract.
/// @return The collateral object.
function getCollateral(IErc20 collateral) external view returns (Collateral memory);
/// @notice Returns the collateral ceiling.
/// @dev It is not an error to provide an invalid address.
/// @param collateral The address of the collateral contract.
/// @return The collateral ceiling as a uint256, or zero if an invalid address was provided.
function getCollateralCeiling(IErc20 collateral) external view returns (uint256);
/// @notice Returns the collateral ratio.
/// @dev It is not an error to provide an invalid address.
/// @param collateral The address of the collateral contract.
/// @return The collateral ratio, or zero if an invalid address was provided.
function getCollateralRatio(IErc20 collateral) external view returns (uint256);
/// @notice Returns the debt ceiling for the given bond.
/// @dev It is not an error to provide an invalid address.
/// @param bond The address of the bond contract.
/// @return The debt ceiling as a uint256, or zero if an invalid address was provided.
function getDebtCeiling(IHToken bond) external view returns (uint256);
/// @notice Checks if collateral deposits are allowed.
/// @dev The collateral must be listed.
/// @param collateral The collateral to make the check against.
/// @return bool true = allowed, false = not allowed.
function getDepositCollateralAllowed(IErc20 collateral) external view returns (bool);
/// @notice Checks if underlying deposits are allowed.
/// @dev The bond must be listed.
/// @param bond The bond to make the check against.
/// @return bool true = allowed, false = not allowed.
function getDepositUnderlyingAllowed(IHToken bond) external view returns (bool);
/// @notice Returns the liquidation incentive of the given collateral.
/// @dev It is not an error to provide an invalid address.
/// @param collateral The address of the collateral contract.
/// @return The liquidation incentive, or zero if an invalid address was provided.
function getLiquidationIncentive(IErc20 collateral) external view returns (uint256);
/// @notice Checks if the account should be allowed to liquidate hToken borrows.
/// @dev The bond must be listed.
/// @param bond The bond to make the check against.
/// @return bool true = allowed, false = not allowed.
function getLiquidateBorrowAllowed(IHToken bond) external view returns (bool);
/// @notice Checks if the account should be allowed to repay borrows.
/// @dev The bond must be listed.
/// @param bond The bond to make the check against.
/// @return bool true = allowed, false = not allowed.
function getRepayBorrowAllowed(IHToken bond) external view returns (bool);
/// @notice Checks if the bond is listed.
/// @param bond The bond to make the check against.
/// @return bool true = listed, otherwise not.
function isBondListed(IHToken bond) external view returns (bool);
/// @notice Checks if the collateral is listed.
/// @param collateral The collateral to make the check against.
/// @return bool true = listed, otherwise not.
function isCollateralListed(IErc20 collateral) external view returns (bool);
/// @notice Returns the maximum number of bond markets a single account can enter.
function maxBonds() external view returns (uint256);
/// @notice Returns the maximum number of Collaterals a single account can deposit.
function maxCollaterals() external view returns (uint256);
/// NON-CONSTANT FUNCTIONS ///
/// @notice Marks the bond as listed in this registry.
///
/// @dev It is not an error to list a bond twice. Emits a {ListBond} event.
///
/// Requirements:
/// - The caller must be the owner.
///
/// @param bond The hToken contract to list.
function listBond(IHToken bond) external;
/// @notice Marks the collateral as listed in this registry.
///
/// @dev Emits a {ListCollateral} event. It is not an error to list a bond twice.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The collateral must have between 1 and 18 decimals.
///
/// @param collateral The collateral contract to list.
function listCollateral(IErc20 collateral) external;
/// @notice Updates the state of the permission accessed by the hToken before a borrow.
///
/// @dev Emits a {SetBorrowAllowed} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The bond must be listed.
///
/// @param bond The bond to update the permission for.
/// @param state The new state to put in storage.
function setBorrowAllowed(IHToken bond, bool state) external;
/// @notice Updates the collateral ceiling.
///
/// @dev Emits a {SetCollateralCeiling} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The collateral must be listed.
///
/// @param collateral The collateral to update the ceiling for.
/// @param newCollateralCeiling The new collateral ceiling.
function setCollateralCeiling(IHToken collateral, uint256 newCollateralCeiling) external;
/// @notice Updates the collateral ratio.
///
/// @dev Emits a {SetCollateralRatio} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The collateral must be listed.
/// - The new collateral ratio cannot be higher than the maximum collateral ratio.
/// - The new collateral ratio cannot be lower than the minimum collateral ratio.
///
/// @param collateral The collateral to update the collateral ratio for.
/// @param newCollateralRatio The new collateral ratio.
function setCollateralRatio(IErc20 collateral, uint256 newCollateralRatio) external;
/// @notice Updates the debt ceiling for the given bond.
///
/// @dev Emits a {SetDebtCeiling} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The bond must be listed.
/// - The debt ceiling cannot fall below the current total supply of hTokens.
///
/// @param bond The bond to update the debt ceiling for.
/// @param newDebtCeiling The new debt ceiling.
function setDebtCeiling(IHToken bond, uint256 newDebtCeiling) external;
/// @notice Updates the state of the permission accessed by the BalanceSheet before a collateral deposit.
///
/// @dev Emits a {SetDepositCollateralAllowed} event.
///
/// Requirements:
/// - The caller must be the owner.
///
/// @param collateral The collateral to update the permission for.
/// @param state The new state to put in storage.
function setDepositCollateralAllowed(IErc20 collateral, bool state) external;
/// @notice Updates the state of the permission accessed by the hToken before an underlying deposit.
///
/// @dev Emits a {SetDepositUnderlyingAllowed} event.
///
/// Requirements:
/// - The caller must be the owner.
///
/// @param bond The bond to update the permission for.
/// @param state The new state to put in storage.
function setDepositUnderlyingAllowed(IHToken bond, bool state) external;
/// @notice Updates the collateral liquidation incentive.
///
/// @dev Emits a {SetLiquidationIncentive} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The collateral must be listed.
/// - The new liquidation incentive cannot be higher than the maximum liquidation incentive.
/// - The new liquidation incentive cannot be lower than the minimum liquidation incentive.
///
/// @param collateral The collateral to update the liquidation incentive for.
/// @param newLiquidationIncentive The new liquidation incentive.
function setLiquidationIncentive(IErc20 collateral, uint256 newLiquidationIncentive) external;
/// @notice Updates the state of the permission accessed by the hToken before a liquidate borrow.
///
/// @dev Emits a {SetLiquidateBorrowAllowed} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The bond must be listed.
///
/// @param bond The hToken contract to update the permission for.
/// @param state The new state to put in storage.
function setLiquidateBorrowAllowed(IHToken bond, bool state) external;
/// @notice Sets max bonds value, which controls how many bond markets a single account can enter.
///
/// @dev Emits a {SetMaxBonds} event.
///
/// Requirements:
/// - The caller must be the owner.
///
/// @param newMaxBonds New max bonds value.
function setMaxBonds(uint256 newMaxBonds) external;
/// @notice Sets max collaterals value, which controls how many collaterals a single account can deposit.
///
/// @dev Emits a {SetMaxCollaterals} event.
///
/// Requirements:
/// - The caller must be the owner.
///
/// @param newMaxCollaterals New max collaterals value.
function setMaxCollaterals(uint256 newMaxCollaterals) external;
/// @notice Updates the state of the permission accessed by the hToken before a repay borrow.
///
/// @dev Emits a {SetRepayBorrowAllowed} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The bond must be listed.
///
/// @param bond The hToken contract to update the permission for.
/// @param state The new state to put in storage.
function setRepayBorrowAllowed(IHToken bond, bool state) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;
import "@prb/contracts/access/IOwnable.sol";
import "@prb/contracts/token/erc20/IErc20.sol";
import "@prb/contracts/token/erc20/IErc20Permit.sol";
import "@prb/contracts/token/erc20/IErc20Recover.sol";
import "../balance-sheet/IBalanceSheetV2.sol";
import "../fintroller/IFintroller.sol";
/// @title IHToken
/// @author Hifi
/// @notice Zero-coupon bond that tracks an Erc20 underlying asset.
interface IHToken is
IOwnable, // no dependency
IErc20Permit, // one dependency
IErc20Recover // one dependency
{
/// CUSTOM ERRORS ///
/// @notice Emitted when the bond matured.
error HToken__BondMatured(uint256 now, uint256 maturity);
/// @notice Emitted when the bond did not mature.
error HToken__BondNotMatured(uint256 now, uint256 maturity);
/// @notice Emitted when burning hTokens and the caller is not the BalanceSheet contract.
error HToken__BurnNotAuthorized(address caller);
/// @notice Emitted when underlying deposits are not allowed by the Fintroller contract.
error HToken__DepositUnderlyingNotAllowed();
/// @notice Emitted when depositing a zero amount of underlying.
error HToken__DepositUnderlyingZero();
/// @notice Emitted when the maturity is in the past.
error HToken__MaturityPassed(uint256 now, uint256 maturity);
/// @notice Emitted when minting hTokens and the caller is not the BalanceSheet contract.
error HToken__MintNotAuthorized(address caller);
/// @notice Emitted when redeeming more underlying that there is in the reserve.
error HToken__RedeemInsufficientLiquidity(uint256 underlyingAmount, uint256 totalUnderlyingReserve);
/// @notice Emitted when redeeming a zero amount of underlying.
error HToken__RedeemZero();
/// @notice Emitted when constructing the contract and the underlying has more than 18 decimals.
error HToken__UnderlyingDecimalsOverflow(uint256 decimals);
/// @notice Emitted when constructing the contract and the underlying has zero decimals.
error HToken__UnderlyingDecimalsZero();
/// @notice Emitted when withdrawing more underlying than there is available.
error HToken__WithdrawUnderlyingUnderflow(address depositor, uint256 availableAmount, uint256 underlyingAmount);
/// @notice Emitted when withdrawing a zero amount of underlying.
error HToken__WithdrawUnderlyingZero();
/// EVENTS ///
/// @notice Emitted when tokens are burnt.
/// @param holder The address of the holder.
/// @param burnAmount The amount of burnt tokens.
event Burn(address indexed holder, uint256 burnAmount);
/// @notice Emitted when underlying is deposited in exchange for an equivalent amount of hTokens.
/// @param depositor The address of the depositor.
/// @param depositUnderlyingAmount The amount of deposited underlying.
/// @param hTokenAmount The amount of minted hTokens.
event DepositUnderlying(address indexed depositor, uint256 depositUnderlyingAmount, uint256 hTokenAmount);
/// @notice Emitted when tokens are minted.
/// @param beneficiary The address of the holder.
/// @param mintAmount The amount of minted tokens.
event Mint(address indexed beneficiary, uint256 mintAmount);
/// @notice Emitted when underlying is redeemed.
/// @param account The account redeeming the underlying.
/// @param underlyingAmount The amount of redeemed underlying.
/// @param hTokenAmount The amount of provided hTokens.
event Redeem(address indexed account, uint256 underlyingAmount, uint256 hTokenAmount);
/// @notice Emitted when the BalanceSheet is set.
/// @param owner The address of the owner.
/// @param oldBalanceSheet The address of the old BalanceSheet.
/// @param newBalanceSheet The address of the new BalanceSheet.
event SetBalanceSheet(address indexed owner, IBalanceSheetV2 oldBalanceSheet, IBalanceSheetV2 newBalanceSheet);
/// @notice Emitted when a depositor withdraws previously deposited underlying.
/// @param depositor The address of the depositor.
/// @param underlyingAmount The amount of withdrawn underlying.
/// @param hTokenAmount The amount of minted hTokens.
event WithdrawUnderlying(address indexed depositor, uint256 underlyingAmount, uint256 hTokenAmount);
/// PUBLIC CONSTANT FUNCTIONS ///
/// @notice Returns the BalanceSheet contract this HToken is connected to.
function balanceSheet() external view returns (IBalanceSheetV2);
/// @notice Returns the balance of the given depositor.
function getDepositorBalance(address depositor) external view returns (uint256 amount);
/// @notice Returns the Fintroller contract this HToken is connected to.
function fintroller() external view returns (IFintroller);
/// @notice Checks if the bond matured.
/// @return bool true = bond matured, otherwise it didn't.
function isMatured() external view returns (bool);
/// @notice Unix timestamp in seconds for when this HToken matures.
function maturity() external view returns (uint256);
/// @notice The amount of underlying redeemable after maturation.
function totalUnderlyingReserve() external view returns (uint256);
/// @notice The Erc20 underlying asset for this HToken.
function underlying() external view returns (IErc20);
/// @notice The ratio between normalized precision (1e18) and the underlying precision.
function underlyingPrecisionScalar() external view returns (uint256);
/// PUBLIC NON-CONSTANT FUNCTIONS ///
/// @notice Destroys `burnAmount` tokens from `holder`, reducing the token supply.
///
/// @dev Emits a {Burn} and a {Transfer} event.
///
/// Requirements:
/// - Can only be called by the BalanceSheet contract.
///
/// @param holder The account whose hTokens to burn.
/// @param burnAmount The amount of hTokens to burn.
function burn(address holder, uint256 burnAmount) external;
/// @notice Deposits underlying in exchange for an equivalent amount of hTokens.
///
/// @dev Emits a {DepositUnderlying} event.
///
/// Requirements:
///
/// - The Fintroller must allow this action to be performed.
/// - The underlying amount to deposit cannot be zero.
/// - The caller must have allowed this contract to spend `underlyingAmount` tokens.
///
/// @param underlyingAmount The amount of underlying to deposit.
function depositUnderlying(uint256 underlyingAmount) external;
/// @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 BalanceSheet contract.
///
/// @param beneficiary The account to mint the hTokens for.
/// @param mintAmount The amount of hTokens to print into existence.
function mint(address beneficiary, uint256 mintAmount) external;
/// @notice Pays the token holder the face value after maturation.
///
/// @dev Emits a {Redeem} event.
///
/// Requirements:
///
/// - Can only be called after maturation.
/// - The amount of underlying to redeem cannot be zero.
/// - There must be enough liquidity in the contract.
///
/// @param underlyingAmount The amount of underlying to redeem.
function redeem(uint256 underlyingAmount) external;
/// @notice Updates the BalanceSheet contract this HToken is connected to.
///
/// @dev Throws a {SetBalanceSheet} event.
///
/// Requirements:
/// - The caller must be the owner.
///
/// @param newBalanceSheet The address of the new BalanceSheet contract.
function _setBalanceSheet(IBalanceSheetV2 newBalanceSheet) external;
/// @notice Withdraws underlying in exchange for hTokens.
///
/// @dev Emits a {WithdrawUnderlying} event.
///
/// Requirements:
///
/// - The underlying amount to withdraw cannot be zero.
/// - Can only be called before maturation.
///
/// @param underlyingAmount The amount of underlying to withdraw.
function withdrawUnderlying(uint256 underlyingAmount) external;
}// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.4;
/// @title IOwnable
/// @author Paul Razvan Berg
/// @notice Contract module that provides a basic access control mechanism, where there is an
/// account (an owner) that can be granted exclusive access to specific functions.
///
/// By default, the owner account will be the one that deploys the contract. This can later be
/// changed with {transfer}.
///
/// This module is used through inheritance. It will make available the modifier `onlyOwner`,
/// which can be applied to your functions to restrict their use to the owner.
///
/// @dev Forked from OpenZeppelin
/// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/access/Ownable.sol
interface IOwnable {
/// EVENTS ///
/// @notice Emitted when ownership is transferred.
/// @param oldOwner The address of the old owner.
/// @param newOwner The address of the new owner.
event TransferOwnership(address indexed oldOwner, address indexed newOwner);
/// NON-CONSTANT FUNCTIONS ///
/// @notice Leaves the contract without owner, so it will not be possible to call `onlyOwner`
/// functions anymore.
///
/// WARNING: Doing this will leave the contract without an owner, thereby removing any
/// functionality that is only available to the owner.
///
/// Requirements:
///
/// - The caller must be the owner.
function _renounceOwnership() external;
/// @notice Transfers the owner of the contract to a new account (`newOwner`). Can only be
/// called by the current owner.
/// @param newOwner The account of the new owner.
function _transferOwnership(address newOwner) external;
/// CONSTANT FUNCTIONS ///
/// @notice The address of the owner account or contract.
/// @return The address of the owner.
function owner() external view returns (address);
}// SPDX-License-Identifier: Unlicense
// solhint-disable func-name-mixedcase
pragma solidity >=0.8.4;
import "./IErc20.sol";
/// @title IErc20Permit
/// @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.
interface IErc20Permit is IErc20 {
/// NON-CONSTANT FUNCTIONS ///
/// @notice Sets `value` as the allowance of `spender` over `owner`'s tokens, assuming the latter's
/// signed approval.
///
/// @dev Emits an {Approval} event.
///
/// IMPORTANT: The same issues Erc20 `approve` has related to transaction
/// ordering also apply here.
///
/// 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 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/// CONSTANT FUNCTIONS ///
/// @notice The Eip712 domain's keccak256 hash.
function DOMAIN_SEPARATOR() external view returns (bytes32);
/// @notice Provides replay protection.
function nonces(address account) external view returns (uint256);
/// @notice keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
function PERMIT_TYPEHASH() external view returns (bytes32);
/// @notice Eip712 version of this implementation.
function version() external view returns (string memory);
}// SPDX-License-Identifier: Unlicense
// solhint-disable var-name-mixedcase
pragma solidity >=0.8.4;
import "./IErc20.sol";
import "../../access/IOwnable.sol";
/// @title IErc20Recover
/// @author Paul Razvan Berg
/// @notice Contract that gives the owner the ability to recover the Erc20 tokens that were sent
/// (accidentally, or not) to the contract.
interface IErc20Recover is IOwnable {
/// EVENTS ///
/// @notice Emitted when tokens are recovered.
/// @param owner The address of the owner recoverring the tokens.
/// @param token The address of the recovered token.
/// @param recoverAmount The amount of recovered tokens.
event Recover(address indexed owner, IErc20 token, uint256 recoverAmount);
/// @notice Emitted when tokens are set as non-recoverable.
/// @param owner The address of the owner calling the function.
/// @param nonRecoverableTokens An array of token addresses.
event SetNonRecoverableTokens(address indexed owner, IErc20[] nonRecoverableTokens);
/// NON-CONSTANT FUNCTIONS ///
/// @notice Recover Erc20 tokens sent to this contract (by accident or otherwise).
/// @dev Emits a {RecoverToken} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - 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(IErc20 token, uint256 recoverAmount) external;
/// @notice Sets the tokens that this contract cannot recover.
///
/// @dev Emits a {SetNonRecoverableTokens} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The contract cannot be already initialized.
///
/// @param tokens The array of tokens to set as non-recoverable.
function _setNonRecoverableTokens(IErc20[] calldata tokens) external;
/// CONSTANT FUNCTIONS ///
/// @notice The tokens that can be recovered cannot be in this mapping.
function nonRecoverableTokens(uint256 index) external view returns (IErc20);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;
import "@prb/contracts/token/erc20/IErc20.sol";
import "../fintroller/IFintroller.sol";
import "../h-token/IHToken.sol";
import "../../access/IOwnableUpgradeable.sol";
import "../../oracles/IChainlinkOperator.sol";
/// @title IBalanceSheetV2
/// @author Hifi
/// @notice Manages the collaterals and the debts for all users.
interface IBalanceSheetV2 is IOwnableUpgradeable {
/// CUSTOM ERRORS ///
/// @notice Emitted when the bond matured.
error BalanceSheet__BondMatured(IHToken bond);
/// @notice Emitted when the account exceeds the maximum numbers of bonds permitted.
error BalanceSheet__BorrowMaxBonds(IHToken bond, uint256 newBondListLength, uint256 maxBonds);
/// @notice Emitted when the account exceeds the maximum numbers of collateral permitted.
error BalanceSheet__DepositMaxCollaterals(
IErc20 collateral,
uint256 newCollateralListLength,
uint256 maxCollaterals
);
/// @notice Emitted when borrows are not allowed by the Fintroller contract.
error BalanceSheet__BorrowNotAllowed(IHToken bond);
/// @notice Emitted when borrowing a zero amount of hTokens.
error BalanceSheet__BorrowZero();
/// @notice Emitted when the new collateral amount exceeds the collateral ceiling.
error BalanceSheet__CollateralCeilingOverflow(uint256 newTotalSupply, uint256 debtCeiling);
/// @notice Emitted when the new total amount of debt exceeds the debt ceiling.
error BalanceSheet__DebtCeilingOverflow(uint256 newCollateralAmount, uint256 debtCeiling);
/// @notice Emitted when collateral deposits are not allowed by the Fintroller contract.
error BalanceSheet__DepositCollateralNotAllowed(IErc20 collateral);
/// @notice Emitted when depositing a zero amount of collateral.
error BalanceSheet__DepositCollateralZero();
/// @notice Emitted when setting the Fintroller contract to the zero address.
error BalanceSheet__FintrollerZeroAddress();
/// @notice Emitted when there is not enough collateral to seize.
error BalanceSheet__LiquidateBorrowInsufficientCollateral(
address account,
uint256 vaultCollateralAmount,
uint256 seizableAmount
);
/// @notice Emitted when borrow liquidations are not allowed by the Fintroller contract.
error BalanceSheet__LiquidateBorrowNotAllowed(IHToken bond);
/// @notice Emitted when the borrower is liquidating themselves.
error BalanceSheet__LiquidateBorrowSelf(address account);
/// @notice Emitted when there is a liquidity shortfall.
error BalanceSheet__LiquidityShortfall(address account, uint256 shortfallLiquidity);
/// @notice Emitted when there is no liquidity shortfall.
error BalanceSheet__NoLiquidityShortfall(address account);
/// @notice Emitted when setting the oracle contract to the zero address.
error BalanceSheet__OracleZeroAddress();
/// @notice Emitted when the repayer does not have enough hTokens to repay the debt.
error BalanceSheet__RepayBorrowInsufficientBalance(IHToken bond, uint256 repayAmount, uint256 hTokenBalance);
/// @notice Emitted when repaying more debt than the borrower owes.
error BalanceSheet__RepayBorrowInsufficientDebt(IHToken bond, uint256 repayAmount, uint256 debtAmount);
/// @notice Emitted when borrow repays are not allowed by the Fintroller contract.
error BalanceSheet__RepayBorrowNotAllowed(IHToken bond);
/// @notice Emitted when repaying a borrow with a zero amount of hTokens.
error BalanceSheet__RepayBorrowZero();
/// @notice Emitted when withdrawing more collateral than there is in the vault.
error BalanceSheet__WithdrawCollateralUnderflow(
address account,
uint256 vaultCollateralAmount,
uint256 withdrawAmount
);
/// @notice Emitted when withdrawing a zero amount of collateral.
error BalanceSheet__WithdrawCollateralZero();
/// EVENTS ///
/// @notice Emitted when a borrow is made.
/// @param account The address of the borrower.
/// @param bond The address of the bond contract.
/// @param borrowAmount The amount of hTokens borrowed.
event Borrow(address indexed account, IHToken indexed bond, uint256 borrowAmount);
/// @notice Emitted when collateral is deposited.
/// @param account The address of the borrower.
/// @param collateral The related collateral.
/// @param collateralAmount The amount of deposited collateral.
event DepositCollateral(address indexed account, IErc20 indexed collateral, uint256 collateralAmount);
/// @notice Emitted when a borrow is liquidated.
/// @param liquidator The address of the liquidator.
/// @param borrower The address of the borrower.
/// @param bond The address of the bond contract.
/// @param repayAmount The amount of repaid funds.
/// @param collateral The address of the collateral contract.
/// @param seizedCollateralAmount The amount of seized collateral.
event LiquidateBorrow(
address indexed liquidator,
address indexed borrower,
IHToken indexed bond,
uint256 repayAmount,
IErc20 collateral,
uint256 seizedCollateralAmount
);
/// @notice Emitted when a borrow is repaid.
/// @param payer The address of the payer.
/// @param borrower The address of the borrower.
/// @param bond The address of the bond contract.
/// @param repayAmount The amount of repaid funds.
/// @param newDebtAmount The amount of the new debt.
event RepayBorrow(
address indexed payer,
address indexed borrower,
IHToken indexed bond,
uint256 repayAmount,
uint256 newDebtAmount
);
/// @notice Emitted when a new Fintroller contract is set.
/// @param owner The address of the owner.
/// @param oldFintroller The address of the old Fintroller contract.
/// @param newFintroller The address of the new Fintroller contract.
event SetFintroller(address indexed owner, address oldFintroller, address newFintroller);
/// @notice Emitted when a new oracle contract is set.
/// @param owner The address of the owner.
/// @param oldOracle The address of the old oracle contract.
/// @param newOracle The address of the new oracle contract.
event SetOracle(address indexed owner, address oldOracle, address newOracle);
/// @notice Emitted when collateral is withdrawn.
/// @param account The address of the borrower.
/// @param collateral The related collateral.
/// @param collateralAmount The amount of withdrawn collateral.
event WithdrawCollateral(address indexed account, IErc20 indexed collateral, uint256 collateralAmount);
/// CONSTANT FUNCTIONS ///
/// @notice Returns the list of bond markets the given account entered.
/// @dev It is not an error to provide an invalid address.
/// @param account The borrower account to make the query against.
function getBondList(address account) external view returns (IHToken[] memory);
/// @notice Returns the amount of collateral deposited by the given account for the given collateral type.
/// @dev It is not an error to provide an invalid address.
/// @param account The borrower account to make the query against.
/// @param collateral The collateral to make the query against.
function getCollateralAmount(address account, IErc20 collateral) external view returns (uint256 collateralAmount);
/// @notice Returns the list of collaterals the given account deposited.
/// @dev It is not an error to provide an invalid address.
/// @param account The borrower account to make the query against.
function getCollateralList(address account) external view returns (IErc20[] memory);
/// @notice Calculates the current account liquidity.
/// @param account The account to make the query against.
/// @return excessLiquidity account liquidity in excess of collateral requirements.
/// @return shortfallLiquidity account shortfall below collateral requirements
function getCurrentAccountLiquidity(address account)
external
view
returns (uint256 excessLiquidity, uint256 shortfallLiquidity);
/// @notice Returns the amount of debt accrued by the given account in the given bond market.
/// @dev It is not an error to provide an invalid address.
/// @param account The borrower account to make the query against.
/// @param bond The bond to make the query against.
function getDebtAmount(address account, IHToken bond) external view returns (uint256 debtAmount);
/// @notice Calculates the account liquidity given a modified collateral, collateral amount, bond and debt amount,
/// using the current prices provided by the oracle.
///
/// @dev Works by summing up each collateral amount multiplied by the USD value of each unit and divided by its
/// respective collateral ratio, then dividing the sum by the total amount of debt drawn by the user.
///
/// Caveats:
/// - This function expects that the "collateralList" and the "bondList" are each modified in advance to include
/// the collateral and bond due to be modified.
///
/// @param account The account to make the query against.
/// @param collateralModify The collateral to make the check against.
/// @param collateralAmountModify The hypothetical normalized amount of collateral.
/// @param bondModify The bond to make the check against.
/// @param debtAmountModify The hypothetical amount of debt.
/// @return excessLiquidity hypothetical account liquidity in excess of collateral requirements.
/// @return shortfallLiquidity hypothetical account shortfall below collateral requirements
function getHypotheticalAccountLiquidity(
address account,
IErc20 collateralModify,
uint256 collateralAmountModify,
IHToken bondModify,
uint256 debtAmountModify
) external view returns (uint256 excessLiquidity, uint256 shortfallLiquidity);
/// @notice Calculates the amount of hTokens that should be repaid in order to seize a given amount of collateral.
/// Note that this is for informational purposes only, it doesn't say anything about whether the user can be
/// liquidated.
/// @dev The formula used is:
/// repayAmount = (seizableCollateralAmount * collateralPriceUsd) / (liquidationIncentive * underlyingPriceUsd)
/// @param collateral The collateral to make the query against.
/// @param seizableCollateralAmount The amount of collateral to seize.
/// @param bond The bond to make the query against.
/// @return repayAmount The amount of hTokens that should be repaid.
function getRepayAmount(
IErc20 collateral,
uint256 seizableCollateralAmount,
IHToken bond
) external view returns (uint256 repayAmount);
/// @notice Calculates the amount of collateral that can be seized when liquidating a borrow. Note that this
/// is for informational purposes only, it doesn't say anything about whether the user can be liquidated.
/// @dev The formula used is:
/// seizableCollateralAmount = repayAmount * liquidationIncentive * underlyingPriceUsd / collateralPriceUsd
/// @param bond The bond to make the query against.
/// @param repayAmount The amount of hTokens to repay.
/// @param collateral The collateral to make the query against.
/// @return seizableCollateralAmount The amount of seizable collateral.
function getSeizableCollateralAmount(
IHToken bond,
uint256 repayAmount,
IErc20 collateral
) external view returns (uint256 seizableCollateralAmount);
/// NON-CONSTANT FUNCTIONS ///
/// @notice Increases the debt of the caller and mints new hTokens.
///
/// @dev Emits a {Borrow} event.
///
/// Requirements:
///
/// - The Fintroller must allow this action to be performed.
/// - The maturity of the bond must be in the future.
/// - The amount to borrow cannot be zero.
/// - The new length of the bond list must be below the max bonds limit.
/// - The new total amount of debt cannot exceed the debt ceiling.
/// - The caller must not end up having a shortfall of liquidity.
///
/// @param bond The address of the bond contract.
/// @param borrowAmount The amount of hTokens to borrow and print into existence.
function borrow(IHToken bond, uint256 borrowAmount) external;
/// @notice Deposits collateral in the caller's account.
///
/// @dev Emits a {DepositCollateral} event.
///
/// Requirements:
///
/// - The Fintroller must allow this action to be performed.
/// - The amount to deposit cannot be zero.
/// - The caller must have allowed this contract to spend `collateralAmount` tokens.
/// - The new collateral amount cannot exceed the collateral ceiling.
///
/// @param collateral The address of the collateral contract.
/// @param depositAmount The amount of collateral to deposit.
function depositCollateral(IErc20 collateral, uint256 depositAmount) external;
/// @notice Repays the debt of the borrower and rewards the caller with a surplus of collateral.
///
/// @dev Emits a {LiquidateBorrow} event.
///
/// Requirements:
///
/// - All from "repayBorrow".
/// - The caller cannot be the same with the borrower.
/// - The Fintroller must allow this action to be performed.
/// - The borrower must have a shortfall of liquidity if the bond didn't mature.
/// - The amount of seized collateral cannot be more than what the borrower has in the vault.
///
/// @param bond The address of the bond contract.
/// @param borrower The account to liquidate.
/// @param repayAmount The amount of hTokens to repay.
/// @param collateral The address of the collateral contract.
function liquidateBorrow(
address borrower,
IHToken bond,
uint256 repayAmount,
IErc20 collateral
) external;
/// @notice Erases the borrower's debt and takes the hTokens out of circulation.
///
/// @dev Emits a {RepayBorrow} event.
///
/// Requirements:
///
/// - The amount to repay cannot be zero.
/// - The Fintroller must allow this action to be performed.
/// - The caller must have at least `repayAmount` hTokens.
/// - The caller must have at least `repayAmount` debt.
///
/// @param bond The address of the bond contract.
/// @param repayAmount The amount of hTokens to repay.
function repayBorrow(IHToken bond, uint256 repayAmount) external;
/// @notice Erases the borrower's debt and takes the hTokens out of circulation.
///
/// @dev Emits a {RepayBorrow} event.
///
/// Requirements:
/// - Same as the `repayBorrow` function, but here `borrower` is the account that must have at least
/// `repayAmount` hTokens to repay the borrow.
///
/// @param borrower The borrower account for which to repay the borrow.
/// @param bond The address of the bond contract
/// @param repayAmount The amount of hTokens to repay.
function repayBorrowBehalf(
address borrower,
IHToken bond,
uint256 repayAmount
) external;
/// @notice Updates the Fintroller contract this BalanceSheet is connected to.
///
/// @dev Emits a {SetFintroller} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The new address cannot be the zero address.
///
/// @param newFintroller The new Fintroller contract.
function setFintroller(IFintroller newFintroller) external;
/// @notice Updates the oracle contract.
///
/// @dev Emits a {SetOracle} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The new address cannot be the zero address.
///
/// @param newOracle The new oracle contract.
function setOracle(IChainlinkOperator newOracle) external;
/// @notice Withdraws a portion or all of the collateral.
///
/// @dev Emits a {WithdrawCollateral} event.
///
/// Requirements:
///
/// - The amount to withdraw cannot be zero.
/// - There must be enough collateral in the vault.
/// - The caller's account cannot fall below the collateral ratio.
///
/// @param collateral The address of the collateral contract.
/// @param withdrawAmount The amount of collateral to withdraw.
function withdrawCollateral(IErc20 collateral, uint256 withdrawAmount) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;
/// @title IOwnableUpgradeable
/// @author Hifi
interface IOwnableUpgradeable {
/// CUSTOM ERRORS ///
/// @notice Emitted when the caller is not the owner.
error OwnableUpgradeable__NotOwner(address owner, address caller);
/// @notice Emitted when setting the owner to the zero address.
error OwnableUpgradeable__OwnerZeroAddress();
/// EVENTS ///
/// @notice Emitted when ownership is transferred.
/// @param oldOwner The address of the old owner.
/// @param newOwner The address of the new owner.
event TransferOwnership(address indexed oldOwner, address indexed newOwner);
/// CONSTANT FUNCTIONS ///
/// @notice The address of the owner account or contract.
/// @return The address of the owner.
function owner() external view returns (address);
/// NON-CONSTANT FUNCTIONS ///
/// @notice Leaves the contract without an owner, so it will not be possible to call `onlyOwner`
/// functions anymore.
///
/// WARNING: Doing this will leave the contract without an owner, thereby removing any
/// functionality that is only available to the owner.
///
/// Requirements:
///
/// - The caller must be the owner.
function _renounceOwnership() external;
/// @notice Transfers the owner of the contract to a new account (`newOwner`). Can only be
/// called by the current owner.
/// @param newOwner The account of the new owner.
function _transferOwnership(address newOwner) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.4;
import "@prb/contracts/token/erc20/IErc20.sol";
import "@prb/contracts/access/IOwnable.sol";
import "../external/chainlink/IAggregatorV3.sol";
/// @title IChainlinkOperator
/// @author Hifi
/// @notice Aggregates the price feeds provided by Chainlink.
interface IChainlinkOperator {
/// CUSTOM ERRORS ///
/// @notice Emitted when the decimal precision of the feed is not the same as the expected number.
error ChainlinkOperator__DecimalsMismatch(string symbol, uint256 decimals);
/// @notice Emitted when trying to interact with a feed not set yet.
error ChainlinkOperator__FeedNotSet(string symbol);
/// @notice Emitted when the price returned by the oracle is less than or equal to zero.
error ChainlinkOperator__PriceLessThanOrEqualToZero(string symbol);
/// @notice Emitted when the latest price update timestamp returned by the oracle is too old.
error ChainlinkOperator__PriceStale(string symbol);
/// EVENTS ///
/// @notice Emitted when a feed is deleted.
/// @param asset The related asset.
/// @param feed The related feed.
event DeleteFeed(IErc20 indexed asset, IAggregatorV3 indexed feed);
/// @notice Emitted when a feed is set.
/// @param asset The related asset.
/// @param feed The related feed.
event SetFeed(IErc20 indexed asset, IAggregatorV3 indexed feed);
/// @notice Emitted when the Chainlink price staleness threshold is set.
/// @param oldPriceStalenessThreshold The old Chainlink price staleness threshold.
/// @param newPriceStalenessThreshold The new Chainlink price staleness threshold.
event SetPriceStalenessThreshold(uint256 oldPriceStalenessThreshold, uint256 newPriceStalenessThreshold);
/// STRUCTS ///
struct Feed {
IErc20 asset;
IAggregatorV3 id;
bool isSet;
}
/// CONSTANT FUNCTIONS ///
/// @notice Gets the official feed for a symbol.
/// @param symbol The symbol to return the feed for.
/// @return (address asset, address id, bool isSet).
function getFeed(string memory symbol)
external
view
returns (
IErc20,
IAggregatorV3,
bool
);
/// @notice Gets the official price for a symbol and adjusts it have 18 decimals instead of the
/// format used by Chainlink, which has 8 decimals.
///
/// @dev Requirements:
/// - The normalized price cannot overflow.
///
/// @param symbol The Erc20 symbol of the token for which to query the price.
/// @return The normalized price.
function getNormalizedPrice(string memory symbol) external view returns (uint256);
/// @notice Gets the official price for a symbol in the default format used by Chainlink, which
/// has 8 decimals.
///
/// @dev Requirements:
///
/// - The feed must be set.
/// - The price returned by the oracle cannot be zero.
///
/// @param symbol The symbol to fetch the price for.
/// @return The price denominated in USD, with 8 decimals.
function getPrice(string memory symbol) external view returns (uint256);
/// @notice Chainlink price precision for USD-quoted data.
function pricePrecision() external view returns (uint256);
/// @notice The ratio between normalized precision (1e18) and the Chainlink price precision (1e8).
function pricePrecisionScalar() external view returns (uint256);
/// @notice The Chainlink price staleness threshold.
function priceStalenessThreshold() external view returns (uint256);
/// NON-CONSTANT FUNCTIONS ///
/// @notice Deletes a previously set Chainlink price feed.
///
/// @dev Emits a {DeleteFeed} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The feed must be set already.
///
/// @param symbol The Erc20 symbol of the asset to delete the feed for.
function deleteFeed(string memory symbol) external;
/// @notice Sets a Chainlink price feed.
///
/// @dev It is not an error to set a feed twice. Emits a {SetFeed} event.
///
/// Requirements:
///
/// - The caller must be the owner.
/// - The number of decimals of the feed must be 8.
///
/// @param asset The address of the Erc20 contract for which to get the price.
/// @param feed The address of the Chainlink price feed contract.
function setFeed(IErc20 asset, IAggregatorV3 feed) external;
/// @notice Sets the Chainlink price staleness threshold.
///
/// @dev Emits a {SetPriceStalenessThreshold} event.
///
/// Requirements:
///
/// - The caller must be the owner.
///
/// @param newPriceStalenessThreshold The new Chainlink price staleness threshold.
function setPriceStalenessThreshold(uint256 newPriceStalenessThreshold) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
/// @title IAggregatorV3
/// @author Hifi
/// @dev Forked from Chainlink
/// github.com/smartcontractkit/chainlink/blob/v1.2.0/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol
interface IAggregatorV3 {
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
);
}{
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"runs": 800
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Fintroller__BondBorrowAllowedWithLiquidateBorrowDisallowed","type":"error"},{"inputs":[],"name":"Fintroller__BondLiquidateBorrowAllowedWithRepayBorrowDisallowed","type":"error"},{"inputs":[],"name":"Fintroller__BondLiquidateBorrowDisallowedWithBorrowAllowed","type":"error"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"}],"name":"Fintroller__BondNotListed","type":"error"},{"inputs":[],"name":"Fintroller__BondRepayBorrowDisallowedWithLiquidateBorrowAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"decimals","type":"uint256"}],"name":"Fintroller__CollateralDecimalsOverflow","type":"error"},{"inputs":[],"name":"Fintroller__CollateralDecimalsZero","type":"error"},{"inputs":[{"internalType":"contract IErc20","name":"collateral","type":"address"}],"name":"Fintroller__CollateralNotListed","type":"error"},{"inputs":[{"internalType":"uint256","name":"newCollateralRatio","type":"uint256"}],"name":"Fintroller__CollateralRatioBelowLiquidationIncentive","type":"error"},{"inputs":[{"internalType":"uint256","name":"newCollateralRatio","type":"uint256"}],"name":"Fintroller__CollateralRatioOverflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"newCollateralRatio","type":"uint256"}],"name":"Fintroller__CollateralRatioUnderflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"newDebtCeiling","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"Fintroller__DebtCeilingUnderflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"newLiquidationIncentive","type":"uint256"}],"name":"Fintroller__LiquidationIncentiveAboveCollateralRatio","type":"error"},{"inputs":[{"internalType":"uint256","name":"newLiquidationIncentive","type":"uint256"}],"name":"Fintroller__LiquidationIncentiveOverflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"newLiquidationIncentive","type":"uint256"}],"name":"Fintroller__LiquidationIncentiveUnderflow","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"caller","type":"address"}],"name":"Ownable__NotOwner","type":"error"},{"inputs":[],"name":"Ownable__OwnerZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"contract IHToken","name":"bond","type":"address"}],"name":"ListBond","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"contract IErc20","name":"collateral","type":"address"}],"name":"ListCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"contract IHToken","name":"bond","type":"address"},{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"SetBorrowAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"contract IErc20","name":"collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldCollateralCeiling","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCollateralCeiling","type":"uint256"}],"name":"SetCollateralCeiling","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"contract IErc20","name":"collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldCollateralRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCollateralRatio","type":"uint256"}],"name":"SetCollateralRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"contract IHToken","name":"bond","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldDebtCeiling","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDebtCeiling","type":"uint256"}],"name":"SetDebtCeiling","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"contract IErc20","name":"collateral","type":"address"},{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"SetDepositCollateralAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"contract IHToken","name":"bond","type":"address"},{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"SetDepositUnderlyingAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"contract IHToken","name":"bond","type":"address"},{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"SetLiquidateBorrowAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"contract IErc20","name":"collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldLiquidationIncentive","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLiquidationIncentive","type":"uint256"}],"name":"SetLiquidationIncentive","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldMaxBonds","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxBonds","type":"uint256"}],"name":"SetMaxBonds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldMaxCollaterals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxCollaterals","type":"uint256"}],"name":"SetMaxCollaterals","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"contract IHToken","name":"bond","type":"address"},{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"SetRepayBorrowAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"TransferOwnership","type":"event"},{"inputs":[],"name":"_renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"_transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"hToken","type":"address"}],"name":"getBond","outputs":[{"components":[{"internalType":"uint256","name":"debtCeiling","type":"uint256"},{"internalType":"bool","name":"isBorrowAllowed","type":"bool"},{"internalType":"bool","name":"isDepositUnderlyingAllowed","type":"bool"},{"internalType":"bool","name":"isLiquidateBorrowAllowed","type":"bool"},{"internalType":"bool","name":"isListed","type":"bool"},{"internalType":"bool","name":"isRepayBorrowAllowed","type":"bool"}],"internalType":"struct IFintroller.Bond","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"}],"name":"getBorrowAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IErc20","name":"collateral","type":"address"}],"name":"getCollateral","outputs":[{"components":[{"internalType":"uint256","name":"ceiling","type":"uint256"},{"internalType":"uint256","name":"ratio","type":"uint256"},{"internalType":"uint256","name":"liquidationIncentive","type":"uint256"},{"internalType":"bool","name":"isDepositCollateralAllowed","type":"bool"},{"internalType":"bool","name":"isListed","type":"bool"}],"internalType":"struct IFintroller.Collateral","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IErc20","name":"collateral","type":"address"}],"name":"getCollateralCeiling","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IErc20","name":"collateral","type":"address"}],"name":"getCollateralRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"}],"name":"getDebtCeiling","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IErc20","name":"collateral","type":"address"}],"name":"getDepositCollateralAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"}],"name":"getDepositUnderlyingAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"}],"name":"getLiquidateBorrowAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IErc20","name":"collateral","type":"address"}],"name":"getLiquidationIncentive","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"}],"name":"getRepayBorrowAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"}],"name":"isBondListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IErc20","name":"collateral","type":"address"}],"name":"isCollateralListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"}],"name":"listBond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IErc20","name":"collateral","type":"address"}],"name":"listCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxBonds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxCollaterals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"setBorrowAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"collateral","type":"address"},{"internalType":"uint256","name":"newCollateralCeiling","type":"uint256"}],"name":"setCollateralCeiling","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IErc20","name":"collateral","type":"address"},{"internalType":"uint256","name":"newCollateralRatio","type":"uint256"}],"name":"setCollateralRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"},{"internalType":"uint256","name":"newDebtCeiling","type":"uint256"}],"name":"setDebtCeiling","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IErc20","name":"collateral","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"setDepositCollateralAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"setDepositUnderlyingAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"setLiquidateBorrowAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IErc20","name":"collateral","type":"address"},{"internalType":"uint256","name":"newLiquidationIncentive","type":"uint256"}],"name":"setLiquidationIncentive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxBonds","type":"uint256"}],"name":"setMaxBonds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxCollaterals","type":"uint256"}],"name":"setMaxCollaterals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IHToken","name":"bond","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"setRepayBorrowAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50600080546001600160a01b031916339081178255604051909182917f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c908290a350600a6001819055600255611b4b8061006b6000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638da5cb5b1161010f578063ce8f6d3e116100a2578063e3ee6e4711610071578063e3ee6e4714610601578063e60f07731461060a578063eecb855d1461061d578063fd0ff4b91461063057600080fd5b8063ce8f6d3e1461059c578063d29d44ee146105af578063d59f3f53146105c2578063d686e9ee146105d557600080fd5b8063aeb4fcc1116100de578063aeb4fcc114610550578063b60b825714610563578063bb23ffec14610576578063c0273a211461058957600080fd5b80638da5cb5b146104905780639b56d6c9146104bb5780639bd8f6e8146105145780639d7385561461052757600080fd5b80633c7981091161018757806363efc2281161015657806363efc228146104215780637922911f1461045757806381a7bc971461046a5780638559d20d1461047d57600080fd5b80633c798109146103ca57806342a4e064146103f35780634b3f2889146104065780635054d1501461040e57600080fd5b806315a3ba43116101c357806315a3ba4314610330578063227661cb1461036a578063298f7b181461037d578063309071a7146103c157600080fd5b806302b5bda7146101ea57806305e18c9d146101ff5780630d8912f314610212575b600080fd5b6101fd6101f8366004611a64565b610643565b005b6101fd61020d366004611a99565b6107e3565b6102d1610220366004611ab2565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506001600160a01b0316600090815260036020908152604091829020825160c0810184528154815260019091015460ff808216151593830193909352610100810483161515938201939093526201000083048216151560608201526301000000830482161515608082015264010000000090920416151560a082015290565b6040516103279190600060c0820190508251825260208301511515602083015260408301511515604083015260608301511515606083015260808301511515608083015260a0830151151560a083015292915050565b60405180910390f35b61035c61033e366004611ab2565b6001600160a01b031660009081526004602052604090206001015490565b604051908152602001610327565b6101fd610378366004611a64565b610878565b6103b161038b366004611ab2565b6001600160a01b0316600090815260046020526040902060030154610100900460ff1690565b6040519015158152602001610327565b61035c60025481565b61035c6103d8366004611ab2565b6001600160a01b031660009081526003602052604090205490565b6101fd610401366004611a64565b6109b7565b6101fd610aae565b6103b161041c366004611ab2565b610b45565b6103b161042f366004611ab2565b6001600160a01b03166000908152600360205260409020600101546301000000900460ff1690565b6101fd610465366004611a64565b610bba565b6103b1610478366004611ab2565b610caa565b6101fd61048b366004611ab2565b610d1a565b6000546104a3906001600160a01b031681565b6040516001600160a01b039091168152602001610327565b6104ce6104c9366004611ab2565b610e4e565b6040516103279190600060a08201905082518252602083015160208301526040830151604083015260608301511515606083015260808301511515608083015292915050565b6101fd610522366004611ad6565b610ee7565b61035c610535366004611ab2565b6001600160a01b031660009081526004602052604090205490565b6101fd61055e366004611ad6565b611077565b6101fd610571366004611ad6565b611204565b6103b1610584366004611ab2565b6112fd565b6101fd610597366004611ab2565b611373565b6103b16105aa366004611ab2565b611524565b6101fd6105bd366004611ab2565b611592565b6101fd6105d0366004611a64565b611661565b61035c6105e3366004611ab2565b6001600160a01b031660009081526004602052604090206002015490565b61035c60015481565b6103b1610618366004611ab2565b6117ab565b6101fd61062b366004611a99565b611823565b6101fd61063e366004611ad6565b6118b0565b6000546001600160a01b031633146106885760005460405163cc6bdb1d60e01b81526001600160a01b0390911660048201523360248201526044015b60405180910390fd5b6001600160a01b0382166000908152600360205260409020600101546301000000900460ff166106d65760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b80801561070757506001600160a01b038216600090815260036020526040902060010154640100000000900460ff16155b15610725576040516313ad546f60e31b815260040160405180910390fd5b8015801561074e57506001600160a01b03821660009081526003602052604090206001015460ff165b1561076c57604051632ed3d4a760e21b815260040160405180910390fd5b6001600160a01b038083166000818152600360205260408082206001018054861515620100000262ff00001990911617905590549051919216907f71dc0d35e1b9ee171f1b8ac9511d05e460ed7416cc401fe4d33978c44f1ca35b906107d790851515815260200190565b60405180910390a35050565b6000546001600160a01b031633146108235760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b600180549082905560005460408051838152602081018590526001600160a01b03909216917ffdc6136113b0185cc0d7209bef28516dcabeae2ebd769f707fcf8710e565656791015b60405180910390a25050565b6000546001600160a01b031633146108b85760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b0382166000908152600360205260409020600101546301000000900460ff166109065760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b80801561093557506001600160a01b03821660009081526003602052604090206001015462010000900460ff16155b1561095357604051630eae82a960e11b815260040160405180910390fd5b6001600160a01b03808316600081815260036020526040808220600101805486151560ff1990911617905590549051919216907fb415ca45b135e3d2eb232571276198ac50330743ec23e7745c78a5b78a0a1b51906107d790851515815260200190565b6000546001600160a01b031633146109f75760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b0382166000908152600360205260409020600101546301000000900460ff16610a455760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b6001600160a01b0380831660008181526003602052604080822060010180548615156101000261ff001990911617905590549051919216907fc55893173627fb718b33144ccc6045fe1b2be87d4f4ab1b4e0460abbfe617c5f906107d790851515815260200190565b6000546001600160a01b03163314610aee5760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b600080546040516001600160a01b03909116907f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c908390a36000805473ffffffffffffffffffffffffffffffffffffffff19169055565b6001600160a01b0381166000908152600360205260408120600101546301000000900460ff16610b935760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b506001600160a01b0316600090815260036020526040902060010154610100900460ff1690565b6000546001600160a01b03163314610bfa5760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b038216600090815260046020526040902060030154610100900460ff16610c4657604051630141c9a760e01b81526001600160a01b038316600482015260240161067f565b6001600160a01b03808316600081815260046020526040808220600301805486151560ff1990911617905590549051919216907f0f3b9071297b60393e9906170c1e2262c9f49e48683463c2268e6b2214a02c82906107d790851515815260200190565b6001600160a01b0381166000908152600360205260408120600101546301000000900460ff16610cf85760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b506001600160a01b031660009081526003602052604090206001015460ff1690565b6000546001600160a01b03163314610d5a5760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6040805160c081018252600080825260016020808401828152848601838152606086018481526080870185815260a088018681526001600160a01b038b8116808a5260039097528a892099518a559451989096018054935192519151965161ffff1990941698151561ff00191698909817610100921515929092029190911763ffff00001916620100009115159190910263ff0000001916176301000000941515949094029390931764ff000000001916640100000000931515939093029290921790935581549351929316917fd81bca3d01ee48c675a3635409a0de9f165d21de38d1b30566de2b764b96cd129190a350565b610e846040518060a001604052806000815260200160008152602001600081526020016000151581526020016000151581525090565b506001600160a01b0316600090815260046020908152604091829020825160a0810184528154815260018201549281019290925260028101549282019290925260039091015460ff80821615156060840152610100909104161515608082015290565b6000546001600160a01b03163314610f275760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b038216600090815260046020526040902060030154610100900460ff16610f7357604051630141c9a760e01b81526001600160a01b038316600482015260240161067f565b6714d1120d7b160000811115610f9f5760405163ba4e26f960e01b81526004810182905260240161067f565b670de0b6b3a7640000811015610fcb57604051633c292c4d60e11b81526004810182905260240161067f565b6001600160a01b03821660009081526004602052604090206001015481111561100a57604051637ab9833b60e01b81526004810182905260240161067f565b6001600160a01b038281166000818152600460209081526040808320600201805490879055925481519485529184018390528301859052909216907f344a32babe164e447da4243dd7af4572ba3e0db01b3644c0fca84ecfb3e66c9f9060600160405180910390a2505050565b6000546001600160a01b031633146110b75760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b0382166000908152600360205260409020600101546301000000900460ff166111055760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b6000826001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611145573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111699190611b02565b90508082101561119657604051635a6bd6d160e01b8152600481018390526024810182905260440161067f565b6001600160a01b0380841660008181526003602052604080822080549087905591549051919316907f722c25b91b159fac5bf2699329b2651dcbf7e2e9470fb0261243e801b9d271b3906111f69085908890918252602082015260400190565b60405180910390a350505050565b6000546001600160a01b031633146112445760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b038216600090815260046020526040902060030154610100900460ff1661129057604051630141c9a760e01b81526001600160a01b038316600482015260240161067f565b6001600160a01b0380831660008181526004602052604080822080549086905591549051919316907f1bb3ad18b0ca1c3aed435a2d1b4caf5ecce0ef121e229a73034dd22815703d4c906112f09085908790918252602082015260400190565b60405180910390a3505050565b6001600160a01b0381166000908152600360205260408120600101546301000000900460ff1661134b5760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b506001600160a01b031660009081526003602052604090206001015462010000900460ff1690565b6000546001600160a01b031633146113b35760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114179190611b1b565b60ff1690508061143a576040516314a5ea3560e11b815260040160405180910390fd5b601281111561145f576040516315432fa560e21b81526004810182905260240161067f565b6040805160a08101825260008082526714d1120d7b1600006020808401918252670f43fc2c04ee0000848601908152600160608601818152608087018281526001600160a01b038b811680895260049096528988209851895595519288019290925591516002870155905160039095018054915161ffff1990921695151561ff00191695909517610100911515919091021790935581549351929316917f6232505455ee4aa22dab92c1da7c3890a53b8f120c0c4e759173b9e33446e2e09190a35050565b6001600160a01b038116600090815260046020526040812060030154610100900460ff1661157057604051630141c9a760e01b81526001600160a01b038316600482015260240161067f565b506001600160a01b031660009081526004602052604090206003015460ff1690565b6000546001600160a01b031633146115d25760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b0381166115f957604051634208fc5d60e01b815260040160405180910390fd5b600080546040516001600160a01b03808516939216917f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c91a36000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b031633146116a15760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b0382166000908152600360205260409020600101546301000000900460ff166116ef5760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b8015801561171e57506001600160a01b03821660009081526003602052604090206001015462010000900460ff165b1561173c576040516335a8f47160e01b815260040160405180910390fd5b6001600160a01b0380831660008181526003602052604080822060010180548615156401000000000264ff000000001990911617905590549051919216907f10424d34f926d4dd41e2f901147ab7b042eac6bf6d1e86205bce22c3744cc426906107d790851515815260200190565b6001600160a01b0381166000908152600360205260408120600101546301000000900460ff166117f95760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b506001600160a01b0316600090815260036020526040902060010154640100000000900460ff1690565b6000546001600160a01b031633146118635760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b600280549082905560005460408051838152602081018590526001600160a01b03909216917fc3fa55da3d00e91f363615e63306100388093bb3ba58877972aa9b84a7dc1959910161086c565b6000546001600160a01b031633146118f05760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b038216600090815260046020526040902060030154610100900460ff1661193c57604051630141c9a760e01b81526001600160a01b038316600482015260240161067f565b68056bc75e2d63100000811115611969576040516321acffb360e11b81526004810182905260240161067f565b670de0b6b3a764000081101561199557604051637444adfb60e11b81526004810182905260240161067f565b6001600160a01b0382166000908152600460205260409020600201548110156119d457604051633c674d3f60e11b81526004810182905260240161067f565b6001600160a01b0380831660008181526004602052604080822060010180549086905591549051919316907f3352e03805e9a22af9ab02ba260864857143dc41b53213d78e1451b98d472ee4906112f09085908790918252602082015260400190565b6001600160a01b0381168114611a4c57600080fd5b50565b80358015158114611a5f57600080fd5b919050565b60008060408385031215611a7757600080fd5b8235611a8281611a37565b9150611a9060208401611a4f565b90509250929050565b600060208284031215611aab57600080fd5b5035919050565b600060208284031215611ac457600080fd5b8135611acf81611a37565b9392505050565b60008060408385031215611ae957600080fd5b8235611af481611a37565b946020939093013593505050565b600060208284031215611b1457600080fd5b5051919050565b600060208284031215611b2d57600080fd5b815160ff81168114611acf57600080fdfea164736f6c634300080c000a
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80638da5cb5b1161010f578063ce8f6d3e116100a2578063e3ee6e4711610071578063e3ee6e4714610601578063e60f07731461060a578063eecb855d1461061d578063fd0ff4b91461063057600080fd5b8063ce8f6d3e1461059c578063d29d44ee146105af578063d59f3f53146105c2578063d686e9ee146105d557600080fd5b8063aeb4fcc1116100de578063aeb4fcc114610550578063b60b825714610563578063bb23ffec14610576578063c0273a211461058957600080fd5b80638da5cb5b146104905780639b56d6c9146104bb5780639bd8f6e8146105145780639d7385561461052757600080fd5b80633c7981091161018757806363efc2281161015657806363efc228146104215780637922911f1461045757806381a7bc971461046a5780638559d20d1461047d57600080fd5b80633c798109146103ca57806342a4e064146103f35780634b3f2889146104065780635054d1501461040e57600080fd5b806315a3ba43116101c357806315a3ba4314610330578063227661cb1461036a578063298f7b181461037d578063309071a7146103c157600080fd5b806302b5bda7146101ea57806305e18c9d146101ff5780630d8912f314610212575b600080fd5b6101fd6101f8366004611a64565b610643565b005b6101fd61020d366004611a99565b6107e3565b6102d1610220366004611ab2565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506001600160a01b0316600090815260036020908152604091829020825160c0810184528154815260019091015460ff808216151593830193909352610100810483161515938201939093526201000083048216151560608201526301000000830482161515608082015264010000000090920416151560a082015290565b6040516103279190600060c0820190508251825260208301511515602083015260408301511515604083015260608301511515606083015260808301511515608083015260a0830151151560a083015292915050565b60405180910390f35b61035c61033e366004611ab2565b6001600160a01b031660009081526004602052604090206001015490565b604051908152602001610327565b6101fd610378366004611a64565b610878565b6103b161038b366004611ab2565b6001600160a01b0316600090815260046020526040902060030154610100900460ff1690565b6040519015158152602001610327565b61035c60025481565b61035c6103d8366004611ab2565b6001600160a01b031660009081526003602052604090205490565b6101fd610401366004611a64565b6109b7565b6101fd610aae565b6103b161041c366004611ab2565b610b45565b6103b161042f366004611ab2565b6001600160a01b03166000908152600360205260409020600101546301000000900460ff1690565b6101fd610465366004611a64565b610bba565b6103b1610478366004611ab2565b610caa565b6101fd61048b366004611ab2565b610d1a565b6000546104a3906001600160a01b031681565b6040516001600160a01b039091168152602001610327565b6104ce6104c9366004611ab2565b610e4e565b6040516103279190600060a08201905082518252602083015160208301526040830151604083015260608301511515606083015260808301511515608083015292915050565b6101fd610522366004611ad6565b610ee7565b61035c610535366004611ab2565b6001600160a01b031660009081526004602052604090205490565b6101fd61055e366004611ad6565b611077565b6101fd610571366004611ad6565b611204565b6103b1610584366004611ab2565b6112fd565b6101fd610597366004611ab2565b611373565b6103b16105aa366004611ab2565b611524565b6101fd6105bd366004611ab2565b611592565b6101fd6105d0366004611a64565b611661565b61035c6105e3366004611ab2565b6001600160a01b031660009081526004602052604090206002015490565b61035c60015481565b6103b1610618366004611ab2565b6117ab565b6101fd61062b366004611a99565b611823565b6101fd61063e366004611ad6565b6118b0565b6000546001600160a01b031633146106885760005460405163cc6bdb1d60e01b81526001600160a01b0390911660048201523360248201526044015b60405180910390fd5b6001600160a01b0382166000908152600360205260409020600101546301000000900460ff166106d65760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b80801561070757506001600160a01b038216600090815260036020526040902060010154640100000000900460ff16155b15610725576040516313ad546f60e31b815260040160405180910390fd5b8015801561074e57506001600160a01b03821660009081526003602052604090206001015460ff165b1561076c57604051632ed3d4a760e21b815260040160405180910390fd5b6001600160a01b038083166000818152600360205260408082206001018054861515620100000262ff00001990911617905590549051919216907f71dc0d35e1b9ee171f1b8ac9511d05e460ed7416cc401fe4d33978c44f1ca35b906107d790851515815260200190565b60405180910390a35050565b6000546001600160a01b031633146108235760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b600180549082905560005460408051838152602081018590526001600160a01b03909216917ffdc6136113b0185cc0d7209bef28516dcabeae2ebd769f707fcf8710e565656791015b60405180910390a25050565b6000546001600160a01b031633146108b85760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b0382166000908152600360205260409020600101546301000000900460ff166109065760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b80801561093557506001600160a01b03821660009081526003602052604090206001015462010000900460ff16155b1561095357604051630eae82a960e11b815260040160405180910390fd5b6001600160a01b03808316600081815260036020526040808220600101805486151560ff1990911617905590549051919216907fb415ca45b135e3d2eb232571276198ac50330743ec23e7745c78a5b78a0a1b51906107d790851515815260200190565b6000546001600160a01b031633146109f75760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b0382166000908152600360205260409020600101546301000000900460ff16610a455760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b6001600160a01b0380831660008181526003602052604080822060010180548615156101000261ff001990911617905590549051919216907fc55893173627fb718b33144ccc6045fe1b2be87d4f4ab1b4e0460abbfe617c5f906107d790851515815260200190565b6000546001600160a01b03163314610aee5760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b600080546040516001600160a01b03909116907f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c908390a36000805473ffffffffffffffffffffffffffffffffffffffff19169055565b6001600160a01b0381166000908152600360205260408120600101546301000000900460ff16610b935760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b506001600160a01b0316600090815260036020526040902060010154610100900460ff1690565b6000546001600160a01b03163314610bfa5760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b038216600090815260046020526040902060030154610100900460ff16610c4657604051630141c9a760e01b81526001600160a01b038316600482015260240161067f565b6001600160a01b03808316600081815260046020526040808220600301805486151560ff1990911617905590549051919216907f0f3b9071297b60393e9906170c1e2262c9f49e48683463c2268e6b2214a02c82906107d790851515815260200190565b6001600160a01b0381166000908152600360205260408120600101546301000000900460ff16610cf85760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b506001600160a01b031660009081526003602052604090206001015460ff1690565b6000546001600160a01b03163314610d5a5760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6040805160c081018252600080825260016020808401828152848601838152606086018481526080870185815260a088018681526001600160a01b038b8116808a5260039097528a892099518a559451989096018054935192519151965161ffff1990941698151561ff00191698909817610100921515929092029190911763ffff00001916620100009115159190910263ff0000001916176301000000941515949094029390931764ff000000001916640100000000931515939093029290921790935581549351929316917fd81bca3d01ee48c675a3635409a0de9f165d21de38d1b30566de2b764b96cd129190a350565b610e846040518060a001604052806000815260200160008152602001600081526020016000151581526020016000151581525090565b506001600160a01b0316600090815260046020908152604091829020825160a0810184528154815260018201549281019290925260028101549282019290925260039091015460ff80821615156060840152610100909104161515608082015290565b6000546001600160a01b03163314610f275760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b038216600090815260046020526040902060030154610100900460ff16610f7357604051630141c9a760e01b81526001600160a01b038316600482015260240161067f565b6714d1120d7b160000811115610f9f5760405163ba4e26f960e01b81526004810182905260240161067f565b670de0b6b3a7640000811015610fcb57604051633c292c4d60e11b81526004810182905260240161067f565b6001600160a01b03821660009081526004602052604090206001015481111561100a57604051637ab9833b60e01b81526004810182905260240161067f565b6001600160a01b038281166000818152600460209081526040808320600201805490879055925481519485529184018390528301859052909216907f344a32babe164e447da4243dd7af4572ba3e0db01b3644c0fca84ecfb3e66c9f9060600160405180910390a2505050565b6000546001600160a01b031633146110b75760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b0382166000908152600360205260409020600101546301000000900460ff166111055760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b6000826001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611145573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111699190611b02565b90508082101561119657604051635a6bd6d160e01b8152600481018390526024810182905260440161067f565b6001600160a01b0380841660008181526003602052604080822080549087905591549051919316907f722c25b91b159fac5bf2699329b2651dcbf7e2e9470fb0261243e801b9d271b3906111f69085908890918252602082015260400190565b60405180910390a350505050565b6000546001600160a01b031633146112445760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b038216600090815260046020526040902060030154610100900460ff1661129057604051630141c9a760e01b81526001600160a01b038316600482015260240161067f565b6001600160a01b0380831660008181526004602052604080822080549086905591549051919316907f1bb3ad18b0ca1c3aed435a2d1b4caf5ecce0ef121e229a73034dd22815703d4c906112f09085908790918252602082015260400190565b60405180910390a3505050565b6001600160a01b0381166000908152600360205260408120600101546301000000900460ff1661134b5760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b506001600160a01b031660009081526003602052604090206001015462010000900460ff1690565b6000546001600160a01b031633146113b35760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114179190611b1b565b60ff1690508061143a576040516314a5ea3560e11b815260040160405180910390fd5b601281111561145f576040516315432fa560e21b81526004810182905260240161067f565b6040805160a08101825260008082526714d1120d7b1600006020808401918252670f43fc2c04ee0000848601908152600160608601818152608087018281526001600160a01b038b811680895260049096528988209851895595519288019290925591516002870155905160039095018054915161ffff1990921695151561ff00191695909517610100911515919091021790935581549351929316917f6232505455ee4aa22dab92c1da7c3890a53b8f120c0c4e759173b9e33446e2e09190a35050565b6001600160a01b038116600090815260046020526040812060030154610100900460ff1661157057604051630141c9a760e01b81526001600160a01b038316600482015260240161067f565b506001600160a01b031660009081526004602052604090206003015460ff1690565b6000546001600160a01b031633146115d25760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b0381166115f957604051634208fc5d60e01b815260040160405180910390fd5b600080546040516001600160a01b03808516939216917f5c486528ec3e3f0ea91181cff8116f02bfa350e03b8b6f12e00765adbb5af85c91a36000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b031633146116a15760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b0382166000908152600360205260409020600101546301000000900460ff166116ef5760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b8015801561171e57506001600160a01b03821660009081526003602052604090206001015462010000900460ff165b1561173c576040516335a8f47160e01b815260040160405180910390fd5b6001600160a01b0380831660008181526003602052604080822060010180548615156401000000000264ff000000001990911617905590549051919216907f10424d34f926d4dd41e2f901147ab7b042eac6bf6d1e86205bce22c3744cc426906107d790851515815260200190565b6001600160a01b0381166000908152600360205260408120600101546301000000900460ff166117f95760405163216a460f60e11b81526001600160a01b038316600482015260240161067f565b506001600160a01b0316600090815260036020526040902060010154640100000000900460ff1690565b6000546001600160a01b031633146118635760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b600280549082905560005460408051838152602081018590526001600160a01b03909216917fc3fa55da3d00e91f363615e63306100388093bb3ba58877972aa9b84a7dc1959910161086c565b6000546001600160a01b031633146118f05760005460405163cc6bdb1d60e01b81526001600160a01b03909116600482015233602482015260440161067f565b6001600160a01b038216600090815260046020526040902060030154610100900460ff1661193c57604051630141c9a760e01b81526001600160a01b038316600482015260240161067f565b68056bc75e2d63100000811115611969576040516321acffb360e11b81526004810182905260240161067f565b670de0b6b3a764000081101561199557604051637444adfb60e11b81526004810182905260240161067f565b6001600160a01b0382166000908152600460205260409020600201548110156119d457604051633c674d3f60e11b81526004810182905260240161067f565b6001600160a01b0380831660008181526004602052604080822060010180549086905591549051919316907f3352e03805e9a22af9ab02ba260864857143dc41b53213d78e1451b98d472ee4906112f09085908790918252602082015260400190565b6001600160a01b0381168114611a4c57600080fd5b50565b80358015158114611a5f57600080fd5b919050565b60008060408385031215611a7757600080fd5b8235611a8281611a37565b9150611a9060208401611a4f565b90509250929050565b600060208284031215611aab57600080fd5b5035919050565b600060208284031215611ac457600080fd5b8135611acf81611a37565b9392505050565b60008060408385031215611ae957600080fd5b8235611af481611a37565b946020939093013593505050565b600060208284031215611b1457600080fd5b5051919050565b600060208284031215611b2d57600080fd5b815160ff81168114611acf57600080fdfea164736f6c634300080c000a
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.