Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
DebtToken
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 1 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import { IERC20, ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { IERC3156FlashBorrower } from "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol";
import {IMetaCore} from "src/interfaces/core/IMetaCore.sol";
/**
@title Debt Token
@notice CDP minted against collateral deposits within `PositionManager`.
This contract has a 1:n relationship with multiple deployments of `PositionManager`,
each of which hold one collateral type which may be used to mint this token.
*/
contract DebtToken is ERC20 {
string public constant version = "1";
// --- ERC 3156 Data ---
bytes32 private constant _RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan");
// --- Data for EIP2612 ---
// keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
bytes32 public constant permitTypeHash = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
// keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
bytes32 private constant _TYPE_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
// Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
// invalidate the cached domain separator if the chain id changes.
bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
uint256 private immutable _CACHED_CHAIN_ID;
bytes32 private immutable _HASHED_NAME;
bytes32 private immutable _HASHED_VERSION;
mapping(address => uint256) private _nonces;
IMetaCore private immutable _metaCore;
address public gasPool;
// --- Addresses ---
/// @dev Whitelist of addresses that are allowed to mint and burn DEBT_TOKEN.
/// @dev Will make DEBT_TOKEN multi-protocol in the future.
mapping(address => bool) public liquidStabilityPools;
mapping(address => bool) public borrowerOperations;
mapping(address => bool) public factories;
mapping(address => bool) public peripheries;
mapping(address => bool) public positionManagers;
mapping(address => bool) public PSMs;
// Amount of debt to be locked in gas pool on opening positions
uint256 public DEBT_GAS_COMPENSATION;
bool definitiveGasCompensation;
event LiquidStabilityPoolWhitelisted(address indexed liquidStabilityPool, bool active);
event BorrowerOperationsWhitelisted(address indexed borrowerOperations, bool active);
event FactoryWhitelisted(address indexed factory, bool active);
event PeripheryWhitelisted(address indexed periphery, bool active);
event GasPoolSet(address indexed gasPool);
event PSMSet(address indexed PSM, bool active);
constructor(
string memory _name,
string memory _symbol,
address _liquidStabilityPool,
address _borrowerOperations,
IMetaCore metaCore_,
address _factory,
address _gasPool,
address _psm,
uint256 _gasCompensation
) ERC20(_name, _symbol) {
if (_liquidStabilityPool == address(0) || _borrowerOperations == address(0) || _factory == address(0) || _gasPool == address(0)) {
revert("Debt: 0 address");
}
liquidStabilityPools[_liquidStabilityPool] = true;
borrowerOperations[_borrowerOperations] = true;
factories[_factory] = true;
PSMs[_psm] = true;
_metaCore = metaCore_;
gasPool = _gasPool;
DEBT_GAS_COMPENSATION = _gasCompensation;
bytes32 hashedName = keccak256(bytes(_name));
bytes32 hashedVersion = keccak256(bytes(version));
_HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion;
_CACHED_CHAIN_ID = block.chainid;
_CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(_TYPE_HASH, hashedName, hashedVersion);
}
function enablePositionManager(address _positionManager) external {
require(factories[msg.sender], "!Factory");
positionManagers[_positionManager] = true;
}
// --- Functions for intra-CDP calls ---
function mintWithGasCompensation(address _account, uint256 _amount) external returns (bool) {
require(borrowerOperations[msg.sender]);
_mint(_account, _amount);
_mint(gasPool, DEBT_GAS_COMPENSATION);
return true;
}
function burnWithGasCompensation(address _account, uint256 _amount) external returns (bool) {
require(borrowerOperations[msg.sender]);
_burn(_account, _amount);
_burn(gasPool, DEBT_GAS_COMPENSATION);
return true;
}
function mint(address _account, uint256 _amount) external {
require(borrowerOperations[msg.sender] || positionManagers[msg.sender] || PSMs[msg.sender], "Debt: Caller not BO/PM");
_mint(_account, _amount);
}
function burn(address _account, uint256 _amount) external {
require(positionManagers[msg.sender] || PSMs[msg.sender], "Debt: Caller not PositionManager");
_burn(_account, _amount);
}
function sendToPeriphery(address _sender, uint256 _amount) external {
require(peripheries[msg.sender], "Debt: Caller not periphery");
_transfer(_sender, msg.sender, _amount);
}
function sendToSP(address _sender, uint256 _amount) external {
require(liquidStabilityPools[msg.sender], "Debt: Caller not StabilityPool");
_transfer(_sender, msg.sender, _amount);
}
function returnFromPool(address _poolAddress, address _receiver, uint256 _amount) external {
require(liquidStabilityPools[msg.sender] || positionManagers[msg.sender], "Debt: Caller not PM/SP");
_transfer(_poolAddress, _receiver, _amount);
}
// --- External functions ---
function transfer(address recipient, uint256 amount) public override returns (bool) {
_requireValidRecipient(recipient);
return super.transfer(recipient, amount);
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) public override returns (bool) {
_requireValidRecipient(recipient);
return super.transferFrom(sender, recipient, amount);
}
// --- ERC 3156 Functions ---
/**
* @dev Returns the maximum amount of tokens available for loan.
* @param token The address of the token that is requested.
* @return The amount of token that can be loaned.
*/
function maxFlashLoan(address token) public view returns (uint256) {
return token == address(this) ? type(uint256).max - totalSupply() : 0;
}
/**
* @dev Returns the fee applied when doing flash loans. This function calls
* the {_flashFee} function which returns the fee applied when doing flash
* loans.
* @param token The token to be flash loaned.
* @param amount The amount of tokens to be loaned.
* @return The fees applied to the corresponding flash loan.
*/
function flashFee(address token, uint256 amount) public view returns (uint256) {
require(token == address(this), "ERC20FlashMint: wrong token");
return _flashFee(amount);
}
/**
* @dev Returns the fee applied when doing flash loans. By default this
* implementation has 0 fees. This function can be overloaded to make
* the flash loan mechanism deflationary.
* @param amount The amount of tokens to be loaned.
* @return The fees applied to the corresponding flash loan.
*/
function _flashFee(uint256 amount) internal view returns (uint256) {
uint effectiveFee = _metaCore.getPeripheryFlashLoanFee(msg.sender);
return (amount * effectiveFee) / 1e4;
}
/**
* @dev Performs a flash loan. New tokens are minted and sent to the
* `receiver`, who is required to implement the {IERC3156FlashBorrower}
* interface. By the end of the flash loan, the receiver is expected to own
* amount + fee tokens and have them approved back to the token contract itself so
* they can be burned.
* @param receiver The receiver of the flash loan. Should implement the
* {IERC3156FlashBorrower-onFlashLoan} interface.
* @param token The token to be flash loaned. Only `address(this)` is
* supported.
* @param amount The amount of tokens to be loaned.
* @param data An arbitrary datafield that is passed to the receiver.
* @return `true` if the flash loan was successful.
*/
// This function can reenter, but it doesn't pose a risk because it always preserves the property that the amount
// minted at the beginning is always recovered and burned at the end, or else the entire function will revert.
// slither-disable-next-line reentrancy-no-eth
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
) external returns (bool) {
uint256 fee = flashFee(token, amount);
require(amount <= maxFlashLoan(token), "ERC20FlashMint: amount exceeds maxFlashLoan");
_mint(address(receiver), amount);
require(
receiver.onFlashLoan(msg.sender, token, amount, fee, data) == _RETURN_VALUE,
"ERC20FlashMint: invalid return value"
);
_spendAllowance(address(receiver), address(this), amount + fee);
_burn(address(receiver), amount);
_transfer(address(receiver), _metaCore.feeReceiver(), fee);
return true;
}
modifier onlyOwner() {
require(_metaCore.owner() == msg.sender, "Caller not Core::owner()");
_;
}
/// @dev Allows DEBT_TOKEN to be protocol transferable
function whitelistLiquidStabilityPoolAddress(address _liquidStabilityPool, bool active) external onlyOwner {
liquidStabilityPools[_liquidStabilityPool] = active;
emit LiquidStabilityPoolWhitelisted(_liquidStabilityPool, active);
}
function whitelistBorrowerOperationsAddress(address _borrowerOperations, bool active) external onlyOwner {
borrowerOperations[_borrowerOperations] = active;
emit BorrowerOperationsWhitelisted(_borrowerOperations, active);
}
function whitelistFactoryAddress(address _factory, bool active) external onlyOwner {
factories[_factory] = active;
emit FactoryWhitelisted(_factory, active);
}
function whitelistPeripheryAddress(address _periphery, bool active) external onlyOwner {
peripheries[_periphery] = active;
emit PeripheryWhitelisted(_periphery, active);
}
function setGasPool(address _gasPool) external onlyOwner {
gasPool = _gasPool;
emit GasPoolSet(_gasPool);
}
function setDebtGasCompensation(uint256 _gasCompensation, bool _isFinalValue) external onlyOwner {
require(!definitiveGasCompensation);
DEBT_GAS_COMPENSATION = _gasCompensation;
definitiveGasCompensation = _isFinalValue;
}
function whitelistPSM(address _psm, bool active) external onlyOwner {
PSMs[_psm] = active;
emit PSMSet(_psm, active);
}
// --- EIP 2612 Functionality ---
function DOMAIN_SEPARATOR() public view returns (bytes32) {
if (block.chainid == _CACHED_CHAIN_ID) {
return _CACHED_DOMAIN_SEPARATOR;
} else {
return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
}
}
function permit(
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external {
require(deadline >= block.timestamp, "Debt: expired deadline");
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(abi.encode(permitTypeHash, owner, spender, amount, _nonces[owner]++, deadline))
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress == owner, "Debt: invalid signature");
_approve(owner, spender, amount);
}
function nonces(address owner) external view returns (uint256) {
// FOR EIP 2612
return _nonces[owner];
}
// --- Internal operations ---
function _buildDomainSeparator(bytes32 typeHash, bytes32 name_, bytes32 version_) private view returns (bytes32) {
return keccak256(abi.encode(typeHash, name_, version_, block.chainid, address(this)));
}
// --- 'require' functions ---
function _requireValidRecipient(address _recipient) internal view {
require(
_recipient != address(0) && _recipient != address(this),
"Debt: Cannot transfer tokens directly to the Debt token contract or the zero address"
);
require(
!positionManagers[_recipient] && !borrowerOperations[_recipient],
"Debt: Cannot transfer tokens directly to the PositionManager or BorrowerOps"
);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC3156 FlashBorrower, as defined in
* https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
*
* _Available since v4.1._
*/
interface IERC3156FlashBorrower {
/**
* @dev Receive a flash loan.
* @param initiator The initiator of the loan.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param fee The additional amount of tokens to repay.
* @param data Arbitrary data structure, intended to contain user-defined parameters.
* @return The keccak256 hash of "IERC3156FlashBorrower.onFlashLoan"
*/
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns (bytes32);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
interface IMetaCore {
// ---------------------------------
// Structures
// ---------------------------------
struct FeeInfo {
bool existsForDebtToken;
uint16 debtTokenFee;
}
struct RebalancerFeeInfo {
bool exists;
uint16 entryFee;
uint16 exitFee;
}
// ---------------------------------
// Public constants
// ---------------------------------
function OWNERSHIP_TRANSFER_DELAY() external view returns (uint256);
function DEFAULT_FLASH_LOAN_FEE() external view returns (uint16);
// ---------------------------------
// Public state variables
// ---------------------------------
function debtToken() external view returns (address);
function lspEntryFee() external view returns (uint16);
function lspExitFee() external view returns (uint16);
function interestProtocolShare() external view returns (uint16);
/// @dev Default interest receiver for all PositionManagers, unless overriden in the respective PM
function defaultInterestReceiver() external view returns (address);
function feeReceiver() external view returns (address);
function priceFeed() external view returns (address);
function owner() external view returns (address);
function pendingOwner() external view returns (address);
function ownershipTransferDeadline() external view returns (uint256);
function guardian() external view returns (address);
function paused() external view returns (bool);
function lspBootstrapPeriod() external view returns (uint64);
// ---------------------------------
// External functions
// ---------------------------------
function setFeeReceiver(address _feeReceiver) external;
function setPriceFeed(address _priceFeed) external;
function setGuardian(address _guardian) external;
/**
* @notice Global pause/unpause
* Pausing halts new deposits/borrowing across the protocol
*/
function setPaused(bool _paused) external;
/**
* @notice Extend or change the LSP bootstrap period,
* after which certain protocol mechanics change
*/
function setLspBootstrapPeriod(uint64 _bootstrapPeriod) external;
/**
* @notice Set a custom flash-loan fee for a given periphery contract
* @param _periphery Target contract that will get this custom fee
* @param _debtTokenFee Fee in basis points (bp)
* @param _existsForDebtToken Whether this custom fee is used when the caller = `debtToken`
*/
function setPeripheryFlashLoanFee(address _periphery, uint16 _debtTokenFee, bool _existsForDebtToken) external;
/**
* @notice Begin the ownership transfer process
* @param newOwner The address proposed to be the new owner
*/
function commitTransferOwnership(address newOwner) external;
/**
* @notice Finish the ownership transfer, after the mandatory delay
*/
function acceptTransferOwnership() external;
/**
* @notice Revoke a pending ownership transfer
*/
function revokeTransferOwnership() external;
/**
* @notice Look up a custom flash-loan fee for a specific periphery contract
* @param peripheryContract The contract that might have a custom fee
* @return The flash-loan fee in basis points
*/
function getPeripheryFlashLoanFee(address peripheryContract) external view returns (uint16);
/**
* @notice Set / override entry & exit fees for a special rebalancer contract
*/
function setRebalancerFee(address _rebalancer, uint16 _entryFee, uint16 _exitFee) external;
/**
* @notice Set the LSP entry fee globally
* @param _fee Fee in basis points
*/
function setEntryFee(uint16 _fee) external;
/**
* @notice Set the LSP exit fee globally
* @param _fee Fee in basis points
*/
function setExitFee(uint16 _fee) external;
/**
* @notice Set the interest protocol share globally to all PositionManagers
* @param _interestProtocolShare Share in basis points
*/
function setInterestProtocolShare(uint16 _interestProtocolShare) external;
/**
* @notice Look up the LSP entry fee for a rebalancer
* @param rebalancer Possibly has a special fee
* @return The entry fee in basis points
*/
function getLspEntryFee(address rebalancer) external view returns (uint16);
/**
* @notice Look up the LSP exit fee for a rebalancer
* @param rebalancer Possibly has a special fee
* @return The exit fee in basis points
*/
function getLspExitFee(address rebalancer) external view returns (uint16);
// ---------------------------------
// Events
// ---------------------------------
event NewOwnerCommitted(address indexed owner, address indexed pendingOwner, uint256 deadline);
event NewOwnerAccepted(address indexed oldOwner, address indexed newOwner);
event NewOwnerRevoked(address indexed owner, address indexed revokedOwner);
event FeeReceiverSet(address indexed feeReceiver);
event PriceFeedSet(address indexed priceFeed);
event GuardianSet(address indexed guardian);
event PeripheryFlashLoanFee(address indexed periphery, uint16 debtTokenFee);
event LSPBootstrapPeriodSet(uint64 bootstrapPeriod);
event RebalancerFees(address indexed rebalancer, uint16 entryFee, uint16 exitFee);
event EntryFeeSet(uint16 fee);
event ExitFeeSet(uint16 fee);
event InterestProtocolShareSet(uint16 interestProtocolShare);
event DefaultInterestReceiverSet(address indexed defaultInterestReceiver);
event Paused();
event Unpaused();
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin-upgradeable/contracts/=lib/openzeppelin-contracts-upgradeable/contracts/",
"solady/=lib/solady/src/",
"@solmate/=lib/solmate/src/",
"@chimera/=lib/chimera/src/",
"forge-std/=lib/forge-std/src/",
"@uniswap/v3-core/=lib/v3-core/",
"@uniswap/v3-periphery/=lib/v3-periphery/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"chimera/=lib/chimera/src/",
"ds-test/=lib/solmate/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"rewards/=lib/rewards/",
"solmate/=lib/solmate/src/",
"uniswap/=lib/uniswap/",
"v3-core/=lib/v3-core/contracts/",
"v3-periphery/=lib/v3-periphery/contracts/"
],
"optimizer": {
"enabled": true,
"runs": 1
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_liquidStabilityPool","type":"address"},{"internalType":"address","name":"_borrowerOperations","type":"address"},{"internalType":"contract IMetaCore","name":"metaCore_","type":"address"},{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_gasPool","type":"address"},{"internalType":"address","name":"_psm","type":"address"},{"internalType":"uint256","name":"_gasCompensation","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrowerOperations","type":"address"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"BorrowerOperationsWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"FactoryWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gasPool","type":"address"}],"name":"GasPoolSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"liquidStabilityPool","type":"address"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"LiquidStabilityPoolWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"PSM","type":"address"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"PSMSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"periphery","type":"address"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"PeripheryWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEBT_GAS_COMPENSATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"PSMs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"borrowerOperations","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnWithGasCompensation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_positionManager","type":"address"}],"name":"enablePositionManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"factories","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC3156FlashBorrower","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gasPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"liquidStabilityPools","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintWithGasCompensation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"peripheries","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"permitTypeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"positionManagers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_poolAddress","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"returnFromPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"sendToPeriphery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"sendToSP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gasCompensation","type":"uint256"},{"internalType":"bool","name":"_isFinalValue","type":"bool"}],"name":"setDebtGasCompensation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gasPool","type":"address"}],"name":"setGasPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrowerOperations","type":"address"},{"internalType":"bool","name":"active","type":"bool"}],"name":"whitelistBorrowerOperationsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"bool","name":"active","type":"bool"}],"name":"whitelistFactoryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_liquidStabilityPool","type":"address"},{"internalType":"bool","name":"active","type":"bool"}],"name":"whitelistLiquidStabilityPoolAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_psm","type":"address"},{"internalType":"bool","name":"active","type":"bool"}],"name":"whitelistPSM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_periphery","type":"address"},{"internalType":"bool","name":"active","type":"bool"}],"name":"whitelistPeripheryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
610120604052348015610010575f80fd5b5060405161287038038061287083398101604081905261002f916102db565b8888600361003d8382610435565b50600461004a8282610435565b5050506001600160a01b038716158061006a57506001600160a01b038616155b8061007c57506001600160a01b038416155b8061008e57506001600160a01b038316155b156100d15760405162461bcd60e51b815260206004820152600f60248201526e446562743a2030206164647265737360881b604482015260640160405180910390fd5b6001600160a01b038781165f9081526007602090815260408083208054600160ff1991821681179092558b8616855260088452828520805482168317905589861685526009845282852080548216831790558786168552600c8452938290208054909416811790935588841661010052600680546001600160a01b03191694881694909417909355600d8490558b518c82012083518085018552928352603160f81b9282019290925260c08281527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660e08190524660a081815286517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8187015280880187905260608101849052608081019290925230828201528651808303909101815292019094528051910120909190608052506104ef9950505050505050505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f83011261023a575f80fd5b81516001600160401b0381111561025357610253610217565b604051601f8201601f19908116603f011681016001600160401b038111828210171561028157610281610217565b604052818152838201602001851015610298575f80fd5b8160208501602083015e5f918101602001919091529392505050565b6001600160a01b03811681146102c8575f80fd5b50565b80516102d6816102b4565b919050565b5f805f805f805f805f6101208a8c0312156102f4575f80fd5b89516001600160401b03811115610309575f80fd5b6103158c828d0161022b565b60208c0151909a5090506001600160401b03811115610332575f80fd5b61033e8c828d0161022b565b98505060408a015161034f816102b4565b965061035d60608b016102cb565b955061036b60808b016102cb565b945061037960a08b016102cb565b935061038760c08b016102cb565b925061039560e08b016102cb565b91505f6101008b01519050809150509295985092959850929598565b600181811c908216806103c557607f821691505b6020821081036103e357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561043057805f5260205f20601f840160051c8101602085101561040e5750805b601f840160051c820191505b8181101561042d575f815560010161041a565b50505b505050565b81516001600160401b0381111561044e5761044e610217565b6104628161045c84546103b1565b846103e9565b6020601f821160018114610494575f831561047d5750848201515b5f19600385901b1c1916600184901b17845561042d565b5f84815260208120601f198516915b828110156104c357878501518255602094850194600190920191016104a3565b50848210156104e057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b60805160a05160c05160e0516101005161230c6105645f395f81816107000152818161081301528181610a9401528181610d2801528181610ebc015281816111760152818161127d015281816113840152611dac01525f61098201525f61095d01525f6108e201525f61090a015261230c5ff3fe608060405234801561000f575f80fd5b50600436106101ec575f3560e01c806306fdde03146101f0578063095ea7b31461020e57806310ce43bd1461023157806318160ddd1461025357806320c582be1461025b57806323b872dd1461027057806324a8d34c1461028357806326a153a514610296578063313ce567146102a95780633644e515146102b857806339509351146102c057806340c10f19146102d35780634ba4a28b146102e657806354fd4d50146102ef5780635c54216a1461030f5780635cffe9de14610322578063613255ab14610335578063696fd3b7146103485780636a2366af1461035b5780636b543b681461037d5780636c7219e71461039057806370a08231146103a35780637ecebe00146103cb5780637f2ac975146103f357806385177509146104155780638cff5fbe1461042857806395d89b411461043b5780639dc29fac14610443578063a457c2d714610456578063a9059cbb14610469578063af3830b21461047c578063be24eaf11461049e578063c0b94e9f146104b1578063c8d053ea146104d3578063d45d2d68146104e6578063d505accf146104f9578063d8d232a21461050c578063d9d98ce41461052e578063dd62ed3e14610541578063e75b3ae714610554578063fa08b03814610567578063fab5268914610587575b5f80fd5b6101f86105a9565b6040516102059190611e52565b60405180910390f35b61022161021c366004611e9b565b610639565b6040519015158152602001610205565b6102455f805160206122b783398151915281565b604051908152602001610205565b600254610245565b61026e610269366004611ec5565b610652565b005b61022161027e366004611ec5565b6106d7565b61026e610291366004611f17565b6106f4565b61026e6102a4366004611f4a565b610807565b60405160128152602001610205565b6102456108df565b6102216102ce366004611e9b565b6109d0565b61026e6102e1366004611e9b565b6109f1565b610245600d5481565b6101f8604051806040016040528060018152602001603160f81b81525081565b61026e61031d366004611f17565b610a88565b610221610330366004611f6b565b610b8f565b610245610343366004612002565b610db9565b61026e610356366004612002565b610dde565b610221610369366004612002565b60076020525f908152604090205460ff1681565b61026e61038b366004611e9b565b610e4a565b61026e61039e366004611f17565b610eb0565b6102456103b1366004612002565b6001600160a01b03165f9081526020819052604090205490565b6102456103d9366004612002565b6001600160a01b03165f9081526005602052604090205490565b610221610401366004612002565b600a6020525f908152604090205460ff1681565b610221610423366004611e9b565b610fb7565b610221610436366004611e9b565b610ffd565b6101f861103a565b61026e610451366004611e9b565b611049565b610221610464366004611e9b565b6110ca565b610221610477366004611e9b565b61114f565b61022161048a366004612002565b600c6020525f908152604090205460ff1681565b61026e6104ac366004611f17565b61116a565b6102216104bf366004612002565b60086020525f908152604090205460ff1681565b61026e6104e1366004611f17565b611271565b61026e6104f4366004612002565b611378565b61026e61050736600461201d565b611471565b61022161051a366004612002565b600b6020525f908152604090205460ff1681565b61024561053c366004611e9b565b61165b565b61024561054f36600461208e565b6116bb565b61026e610562366004611e9b565b6116e5565b60065461057a906001600160a01b031681565b60405161020591906120c5565b610221610595366004612002565b60096020525f908152604090205460ff1681565b6060600380546105b8906120d9565b80601f01602080910402602001604051908101604052809291908181526020018280546105e4906120d9565b801561062f5780601f106106065761010080835404028352916020019161062f565b820191905f5260205f20905b81548152906001019060200180831161061257829003601f168201915b5050505050905090565b5f33610646818585611743565b60019150505b92915050565b335f9081526007602052604090205460ff168061067d5750335f908152600b602052604090205460ff165b6106c75760405162461bcd60e51b81526020600482015260166024820152750446562743a2043616c6c6572206e6f7420504d2f53560541b60448201526064015b60405180910390fd5b6106d2838383611866565b505050565b5f6106e1836119f7565b6106ec848484611b4a565b949350505050565b336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561075a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061077e9190612111565b6001600160a01b0316146107a45760405162461bcd60e51b81526004016106be9061212c565b6001600160a01b0382165f818152600a602052604090819020805460ff1916841515179055517f0f3e23d9f4c143cfb9669f0f5414551da120d83e0a9d3f215787f9abeee4de9c906107fb90841515815260200190565b60405180910390a25050565b336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561086d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108919190612111565b6001600160a01b0316146108b75760405162461bcd60e51b81526004016106be9061212c565b600e5460ff16156108c6575f80fd5b600d91909155600e805460ff1916911515919091179055565b5f7f0000000000000000000000000000000000000000000000000000000000000000460361092c57507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b5f336106468185856109e283836116bb565b6109ec9190612172565b611743565b335f9081526008602052604090205460ff1680610a1c5750335f908152600b602052604090205460ff165b80610a355750335f908152600c602052604090205460ff165b610a7a5760405162461bcd60e51b8152602060048201526016602482015275446562743a2043616c6c6572206e6f7420424f2f504d60501b60448201526064016106be565b610a848282611b62565b5050565b336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aee573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b129190612111565b6001600160a01b031614610b385760405162461bcd60e51b81526004016106be9061212c565b6001600160a01b0382165f818152600c602052604090819020805460ff1916841515179055517f578955053ae789a7f66bb868d2e0731f62a1ded138cbcf8c056df44fbb341868906107fb90841515815260200190565b5f80610b9b868661165b565b9050610ba686610db9565b851115610c095760405162461bcd60e51b815260206004820152602b60248201527f4552433230466c6173684d696e743a20616d6f756e742065786365656473206d60448201526a30bc233630b9b42637b0b760a91b60648201526084016106be565b610c138786611b62565b6040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9906001600160a01b038916906323e30c8b90610c6b9033908b908b9088908c908c90600401612185565b6020604051808303815f875af1158015610c87573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cab91906121dd565b14610d045760405162461bcd60e51b8152602060048201526024808201527f4552433230466c6173684d696e743a20696e76616c69642072657475726e2076604482015263616c756560e01b60648201526084016106be565b610d188730610d138489612172565b611c0c565b610d228786611c7e565b610dac877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b3f006746040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d82573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610da69190612111565b83611866565b5060019695505050505050565b5f6001600160a01b0382163014610dd0575f61064c565b60025461064c905f196121f4565b335f9081526009602052604090205460ff16610e275760405162461bcd60e51b815260206004820152600860248201526721466163746f727960c01b60448201526064016106be565b6001600160a01b03165f908152600b60205260409020805460ff19166001179055565b335f908152600a602052604090205460ff16610ea55760405162461bcd60e51b815260206004820152601a602482015279446562743a2043616c6c6572206e6f742070657269706865727960301b60448201526064016106be565b610a84823383611866565b336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f3a9190612111565b6001600160a01b031614610f605760405162461bcd60e51b81526004016106be9061212c565b6001600160a01b0382165f8181526009602052604090819020805460ff1916841515179055517f22beee31da954d00dc9ac528e6f845d3912b40ddb4ab6db620876632299374e7906107fb90841515815260200190565b335f9081526008602052604081205460ff16610fd1575f80fd5b610fdb8383611c7e565b600654600d54610ff4916001600160a01b031690611c7e565b50600192915050565b335f9081526008602052604081205460ff16611017575f80fd5b6110218383611b62565b600654600d54610ff4916001600160a01b031690611b62565b6060600480546105b8906120d9565b335f908152600b602052604090205460ff16806110745750335f908152600c602052604090205460ff165b6110c05760405162461bcd60e51b815260206004820181905260248201527f446562743a2043616c6c6572206e6f7420506f736974696f6e4d616e6167657260448201526064016106be565b610a848282611c7e565b5f33816110d782866116bb565b9050838110156111375760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106be565b6111448286868403611743565b506001949350505050565b5f611159836119f7565b6111638383611d9b565b9392505050565b336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111f49190612111565b6001600160a01b03161461121a5760405162461bcd60e51b81526004016106be9061212c565b6001600160a01b0382165f8181526008602052604090819020805460ff1916841515179055517faae17410fcabb9af97b361d2e164bbb6307097658c0281882774d70ca022f03a906107fb90841515815260200190565b336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112fb9190612111565b6001600160a01b0316146113215760405162461bcd60e51b81526004016106be9061212c565b6001600160a01b0382165f8181526007602052604090819020805460ff1916841515179055517f70df214290d7c0aff431642b22bbf9b1e2ed6b449b1a5a33c653f5955a2baddf906107fb90841515815260200190565b336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113de573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114029190612111565b6001600160a01b0316146114285760405162461bcd60e51b81526004016106be9061212c565b600680546001600160a01b0319166001600160a01b0383169081179091556040517f2e2d80f5010c461d5624860d67bb3ea4eae961857d70642f8677f684d22f31dd905f90a250565b428410156114ba5760405162461bcd60e51b8152602060048201526016602482015275446562743a206578706972656420646561646c696e6560501b60448201526064016106be565b5f6114c36108df565b6001600160a01b0389165f90815260056020526040812080545f805160206122b7833981519152928c928c928c929091906114fd83612207565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161157692919061190160f01b81526002810192909252602282015260420190565b60408051601f1981840301815282825280516020918201205f80855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa1580156115de573d5f803e3d5ffd5b505050602060405103519050886001600160a01b0316816001600160a01b0316146116455760405162461bcd60e51b8152602060048201526017602482015276446562743a20696e76616c6964207369676e617475726560481b60448201526064016106be565b611650898989611743565b505050505050505050565b5f6001600160a01b03831630146116b25760405162461bcd60e51b815260206004820152601b60248201527a22a9219918233630b9b426b4b73a1d103bb937b733903a37b5b2b760291b60448201526064016106be565b61116382611da8565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b335f9081526007602052604090205460ff16610ea55760405162461bcd60e51b815260206004820152601e60248201527f446562743a2043616c6c6572206e6f742053746162696c697479506f6f6c000060448201526064016106be565b6001600160a01b0383166117a55760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106be565b6001600160a01b0382166118065760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106be565b6001600160a01b038381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166118ca5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106be565b6001600160a01b03821661192c5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106be565b6001600160a01b0383165f90815260208190526040902054818110156119a35760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106be565b6001600160a01b038481165f81815260208181526040808320878703905593871680835291849020805487019055925185815290925f80516020612297833981519152910160405180910390a35b50505050565b6001600160a01b03811615801590611a1857506001600160a01b0381163014155b611a945760405162461bcd60e51b815260206004820152605460248201525f8051602061227783398151915260448201527f6563746c7920746f20746865204465627420746f6b656e20636f6e7472616374606482015273206f7220746865207a65726f206164647265737360601b608482015260a4016106be565b6001600160a01b0381165f908152600b602052604090205460ff16158015611ad457506001600160a01b0381165f9081526008602052604090205460ff16155b611b475760405162461bcd60e51b815260206004820152604b60248201525f8051602061227783398151915260448201527f6563746c7920746f2074686520506f736974696f6e4d616e61676572206f722060648201526a426f72726f7765724f707360a81b608482015260a4016106be565b50565b5f33611b57858285611c0c565b611144858585611866565b6001600160a01b038216611bb85760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106be565b8060025f828254611bc99190612172565b90915550506001600160a01b0382165f81815260208181526040808320805486019055518481525f80516020612297833981519152910160405180910390a35050565b5f611c1784846116bb565b90505f1981146119f15781811015611c715760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106be565b6119f18484848403611743565b6001600160a01b038216611cde5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106be565b6001600160a01b0382165f9081526020819052604090205481811015611d515760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106be565b6001600160a01b0383165f818152602081815260408083208686039055600280548790039055518581529192915f80516020612297833981519152910160405180910390a3505050565b5f33610646818585611866565b5f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6da51a4336040518263ffffffff1660e01b8152600401611df691906120c5565b602060405180830381865afa158015611e11573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e35919061221f565b61ffff169050612710611e488285612240565b6111639190612257565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114611b47575f80fd5b5f8060408385031215611eac575f80fd5b8235611eb781611e87565b946020939093013593505050565b5f805f60608486031215611ed7575f80fd5b8335611ee281611e87565b92506020840135611ef281611e87565b929592945050506040919091013590565b80358015158114611f12575f80fd5b919050565b5f8060408385031215611f28575f80fd5b8235611f3381611e87565b9150611f4160208401611f03565b90509250929050565b5f8060408385031215611f5b575f80fd5b82359150611f4160208401611f03565b5f805f805f60808688031215611f7f575f80fd5b8535611f8a81611e87565b94506020860135611f9a81611e87565b93506040860135925060608601356001600160401b03811115611fbb575f80fd5b8601601f81018813611fcb575f80fd5b80356001600160401b03811115611fe0575f80fd5b886020828401011115611ff1575f80fd5b959894975092955050506020019190565b5f60208284031215612012575f80fd5b813561116381611e87565b5f805f805f805f60e0888a031215612033575f80fd5b873561203e81611e87565b9650602088013561204e81611e87565b95506040880135945060608801359350608088013560ff81168114612071575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f806040838503121561209f575f80fd5b82356120aa81611e87565b915060208301356120ba81611e87565b809150509250929050565b6001600160a01b0391909116815260200190565b600181811c908216806120ed57607f821691505b60208210810361210b57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215612121575f80fd5b815161116381611e87565b60208082526018908201527743616c6c6572206e6f7420436f72653a3a6f776e6572282960401b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561064c5761064c61215e565b6001600160a01b03878116825286166020820152604081018590526060810184905260a0608082018190528101829052818360c08301375f81830160c090810191909152601f909201601f1916010195945050505050565b5f602082840312156121ed575f80fd5b5051919050565b8181038181111561064c5761064c61215e565b5f600182016122185761221861215e565b5060010190565b5f6020828403121561222f575f80fd5b815161ffff81168114611163575f80fd5b808202811582820484141761064c5761064c61215e565b5f8261227157634e487b7160e01b5f52601260045260245ffd5b50049056fe446562743a2043616e6e6f74207472616e7366657220746f6b656e7320646972ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9a2646970667358221220d4f080349f92ce3ecc9a9662a7cff368c76824556c4540a7d35f2a2f17f128a064736f6c634300081a00330000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000044bc1c218d3ee787ca222c09a5b30e090bf9621700000000000000000000000049fd0c4fb5172b20b7636b13c49fb15da52d5bd40000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce80000000000000000000000004e8781e422a5e6fa1a422d6f6c6938111446f906000000000000000000000000130541a39cfaa89c9ed8f387d479b277321d1ad400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000034b4149000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034b41490000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106101ec575f3560e01c806306fdde03146101f0578063095ea7b31461020e57806310ce43bd1461023157806318160ddd1461025357806320c582be1461025b57806323b872dd1461027057806324a8d34c1461028357806326a153a514610296578063313ce567146102a95780633644e515146102b857806339509351146102c057806340c10f19146102d35780634ba4a28b146102e657806354fd4d50146102ef5780635c54216a1461030f5780635cffe9de14610322578063613255ab14610335578063696fd3b7146103485780636a2366af1461035b5780636b543b681461037d5780636c7219e71461039057806370a08231146103a35780637ecebe00146103cb5780637f2ac975146103f357806385177509146104155780638cff5fbe1461042857806395d89b411461043b5780639dc29fac14610443578063a457c2d714610456578063a9059cbb14610469578063af3830b21461047c578063be24eaf11461049e578063c0b94e9f146104b1578063c8d053ea146104d3578063d45d2d68146104e6578063d505accf146104f9578063d8d232a21461050c578063d9d98ce41461052e578063dd62ed3e14610541578063e75b3ae714610554578063fa08b03814610567578063fab5268914610587575b5f80fd5b6101f86105a9565b6040516102059190611e52565b60405180910390f35b61022161021c366004611e9b565b610639565b6040519015158152602001610205565b6102455f805160206122b783398151915281565b604051908152602001610205565b600254610245565b61026e610269366004611ec5565b610652565b005b61022161027e366004611ec5565b6106d7565b61026e610291366004611f17565b6106f4565b61026e6102a4366004611f4a565b610807565b60405160128152602001610205565b6102456108df565b6102216102ce366004611e9b565b6109d0565b61026e6102e1366004611e9b565b6109f1565b610245600d5481565b6101f8604051806040016040528060018152602001603160f81b81525081565b61026e61031d366004611f17565b610a88565b610221610330366004611f6b565b610b8f565b610245610343366004612002565b610db9565b61026e610356366004612002565b610dde565b610221610369366004612002565b60076020525f908152604090205460ff1681565b61026e61038b366004611e9b565b610e4a565b61026e61039e366004611f17565b610eb0565b6102456103b1366004612002565b6001600160a01b03165f9081526020819052604090205490565b6102456103d9366004612002565b6001600160a01b03165f9081526005602052604090205490565b610221610401366004612002565b600a6020525f908152604090205460ff1681565b610221610423366004611e9b565b610fb7565b610221610436366004611e9b565b610ffd565b6101f861103a565b61026e610451366004611e9b565b611049565b610221610464366004611e9b565b6110ca565b610221610477366004611e9b565b61114f565b61022161048a366004612002565b600c6020525f908152604090205460ff1681565b61026e6104ac366004611f17565b61116a565b6102216104bf366004612002565b60086020525f908152604090205460ff1681565b61026e6104e1366004611f17565b611271565b61026e6104f4366004612002565b611378565b61026e61050736600461201d565b611471565b61022161051a366004612002565b600b6020525f908152604090205460ff1681565b61024561053c366004611e9b565b61165b565b61024561054f36600461208e565b6116bb565b61026e610562366004611e9b565b6116e5565b60065461057a906001600160a01b031681565b60405161020591906120c5565b610221610595366004612002565b60096020525f908152604090205460ff1681565b6060600380546105b8906120d9565b80601f01602080910402602001604051908101604052809291908181526020018280546105e4906120d9565b801561062f5780601f106106065761010080835404028352916020019161062f565b820191905f5260205f20905b81548152906001019060200180831161061257829003601f168201915b5050505050905090565b5f33610646818585611743565b60019150505b92915050565b335f9081526007602052604090205460ff168061067d5750335f908152600b602052604090205460ff165b6106c75760405162461bcd60e51b81526020600482015260166024820152750446562743a2043616c6c6572206e6f7420504d2f53560541b60448201526064015b60405180910390fd5b6106d2838383611866565b505050565b5f6106e1836119f7565b6106ec848484611b4a565b949350505050565b336001600160a01b03167f0000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce86001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561075a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061077e9190612111565b6001600160a01b0316146107a45760405162461bcd60e51b81526004016106be9061212c565b6001600160a01b0382165f818152600a602052604090819020805460ff1916841515179055517f0f3e23d9f4c143cfb9669f0f5414551da120d83e0a9d3f215787f9abeee4de9c906107fb90841515815260200190565b60405180910390a25050565b336001600160a01b03167f0000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce86001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561086d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108919190612111565b6001600160a01b0316146108b75760405162461bcd60e51b81526004016106be9061212c565b600e5460ff16156108c6575f80fd5b600d91909155600e805460ff1916911515919091179055565b5f7f00000000000000000000000000000000000000000000000000000000000b67d2460361092c57507fd1e3547b50626b96c7fa5c855f5ad37a79ac0f3edcfcc0abfb291b42bcda9e7590565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f7d787f7cf402947f4bf6f00da5107ca3025a77e6ba9155e20bebe7ae892538da828401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b5f336106468185856109e283836116bb565b6109ec9190612172565b611743565b335f9081526008602052604090205460ff1680610a1c5750335f908152600b602052604090205460ff165b80610a355750335f908152600c602052604090205460ff165b610a7a5760405162461bcd60e51b8152602060048201526016602482015275446562743a2043616c6c6572206e6f7420424f2f504d60501b60448201526064016106be565b610a848282611b62565b5050565b336001600160a01b03167f0000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce86001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aee573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b129190612111565b6001600160a01b031614610b385760405162461bcd60e51b81526004016106be9061212c565b6001600160a01b0382165f818152600c602052604090819020805460ff1916841515179055517f578955053ae789a7f66bb868d2e0731f62a1ded138cbcf8c056df44fbb341868906107fb90841515815260200190565b5f80610b9b868661165b565b9050610ba686610db9565b851115610c095760405162461bcd60e51b815260206004820152602b60248201527f4552433230466c6173684d696e743a20616d6f756e742065786365656473206d60448201526a30bc233630b9b42637b0b760a91b60648201526084016106be565b610c138786611b62565b6040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9906001600160a01b038916906323e30c8b90610c6b9033908b908b9088908c908c90600401612185565b6020604051808303815f875af1158015610c87573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cab91906121dd565b14610d045760405162461bcd60e51b8152602060048201526024808201527f4552433230466c6173684d696e743a20696e76616c69642072657475726e2076604482015263616c756560e01b60648201526084016106be565b610d188730610d138489612172565b611c0c565b610d228786611c7e565b610dac877f0000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce86001600160a01b031663b3f006746040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d82573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610da69190612111565b83611866565b5060019695505050505050565b5f6001600160a01b0382163014610dd0575f61064c565b60025461064c905f196121f4565b335f9081526009602052604090205460ff16610e275760405162461bcd60e51b815260206004820152600860248201526721466163746f727960c01b60448201526064016106be565b6001600160a01b03165f908152600b60205260409020805460ff19166001179055565b335f908152600a602052604090205460ff16610ea55760405162461bcd60e51b815260206004820152601a602482015279446562743a2043616c6c6572206e6f742070657269706865727960301b60448201526064016106be565b610a84823383611866565b336001600160a01b03167f0000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce86001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f3a9190612111565b6001600160a01b031614610f605760405162461bcd60e51b81526004016106be9061212c565b6001600160a01b0382165f8181526009602052604090819020805460ff1916841515179055517f22beee31da954d00dc9ac528e6f845d3912b40ddb4ab6db620876632299374e7906107fb90841515815260200190565b335f9081526008602052604081205460ff16610fd1575f80fd5b610fdb8383611c7e565b600654600d54610ff4916001600160a01b031690611c7e565b50600192915050565b335f9081526008602052604081205460ff16611017575f80fd5b6110218383611b62565b600654600d54610ff4916001600160a01b031690611b62565b6060600480546105b8906120d9565b335f908152600b602052604090205460ff16806110745750335f908152600c602052604090205460ff165b6110c05760405162461bcd60e51b815260206004820181905260248201527f446562743a2043616c6c6572206e6f7420506f736974696f6e4d616e6167657260448201526064016106be565b610a848282611c7e565b5f33816110d782866116bb565b9050838110156111375760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016106be565b6111448286868403611743565b506001949350505050565b5f611159836119f7565b6111638383611d9b565b9392505050565b336001600160a01b03167f0000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce86001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111f49190612111565b6001600160a01b03161461121a5760405162461bcd60e51b81526004016106be9061212c565b6001600160a01b0382165f8181526008602052604090819020805460ff1916841515179055517faae17410fcabb9af97b361d2e164bbb6307097658c0281882774d70ca022f03a906107fb90841515815260200190565b336001600160a01b03167f0000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce86001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112fb9190612111565b6001600160a01b0316146113215760405162461bcd60e51b81526004016106be9061212c565b6001600160a01b0382165f8181526007602052604090819020805460ff1916841515179055517f70df214290d7c0aff431642b22bbf9b1e2ed6b449b1a5a33c653f5955a2baddf906107fb90841515815260200190565b336001600160a01b03167f0000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce86001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113de573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114029190612111565b6001600160a01b0316146114285760405162461bcd60e51b81526004016106be9061212c565b600680546001600160a01b0319166001600160a01b0383169081179091556040517f2e2d80f5010c461d5624860d67bb3ea4eae961857d70642f8677f684d22f31dd905f90a250565b428410156114ba5760405162461bcd60e51b8152602060048201526016602482015275446562743a206578706972656420646561646c696e6560501b60448201526064016106be565b5f6114c36108df565b6001600160a01b0389165f90815260056020526040812080545f805160206122b7833981519152928c928c928c929091906114fd83612207565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161157692919061190160f01b81526002810192909252602282015260420190565b60408051601f1981840301815282825280516020918201205f80855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa1580156115de573d5f803e3d5ffd5b505050602060405103519050886001600160a01b0316816001600160a01b0316146116455760405162461bcd60e51b8152602060048201526017602482015276446562743a20696e76616c6964207369676e617475726560481b60448201526064016106be565b611650898989611743565b505050505050505050565b5f6001600160a01b03831630146116b25760405162461bcd60e51b815260206004820152601b60248201527a22a9219918233630b9b426b4b73a1d103bb937b733903a37b5b2b760291b60448201526064016106be565b61116382611da8565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b335f9081526007602052604090205460ff16610ea55760405162461bcd60e51b815260206004820152601e60248201527f446562743a2043616c6c6572206e6f742053746162696c697479506f6f6c000060448201526064016106be565b6001600160a01b0383166117a55760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016106be565b6001600160a01b0382166118065760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016106be565b6001600160a01b038381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166118ca5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016106be565b6001600160a01b03821661192c5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016106be565b6001600160a01b0383165f90815260208190526040902054818110156119a35760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016106be565b6001600160a01b038481165f81815260208181526040808320878703905593871680835291849020805487019055925185815290925f80516020612297833981519152910160405180910390a35b50505050565b6001600160a01b03811615801590611a1857506001600160a01b0381163014155b611a945760405162461bcd60e51b815260206004820152605460248201525f8051602061227783398151915260448201527f6563746c7920746f20746865204465627420746f6b656e20636f6e7472616374606482015273206f7220746865207a65726f206164647265737360601b608482015260a4016106be565b6001600160a01b0381165f908152600b602052604090205460ff16158015611ad457506001600160a01b0381165f9081526008602052604090205460ff16155b611b475760405162461bcd60e51b815260206004820152604b60248201525f8051602061227783398151915260448201527f6563746c7920746f2074686520506f736974696f6e4d616e61676572206f722060648201526a426f72726f7765724f707360a81b608482015260a4016106be565b50565b5f33611b57858285611c0c565b611144858585611866565b6001600160a01b038216611bb85760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016106be565b8060025f828254611bc99190612172565b90915550506001600160a01b0382165f81815260208181526040808320805486019055518481525f80516020612297833981519152910160405180910390a35050565b5f611c1784846116bb565b90505f1981146119f15781811015611c715760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016106be565b6119f18484848403611743565b6001600160a01b038216611cde5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016106be565b6001600160a01b0382165f9081526020819052604090205481811015611d515760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016106be565b6001600160a01b0383165f818152602081815260408083208686039055600280548790039055518581529192915f80516020612297833981519152910160405180910390a3505050565b5f33610646818585611866565b5f807f0000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce86001600160a01b031663e6da51a4336040518263ffffffff1660e01b8152600401611df691906120c5565b602060405180830381865afa158015611e11573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e35919061221f565b61ffff169050612710611e488285612240565b6111639190612257565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114611b47575f80fd5b5f8060408385031215611eac575f80fd5b8235611eb781611e87565b946020939093013593505050565b5f805f60608486031215611ed7575f80fd5b8335611ee281611e87565b92506020840135611ef281611e87565b929592945050506040919091013590565b80358015158114611f12575f80fd5b919050565b5f8060408385031215611f28575f80fd5b8235611f3381611e87565b9150611f4160208401611f03565b90509250929050565b5f8060408385031215611f5b575f80fd5b82359150611f4160208401611f03565b5f805f805f60808688031215611f7f575f80fd5b8535611f8a81611e87565b94506020860135611f9a81611e87565b93506040860135925060608601356001600160401b03811115611fbb575f80fd5b8601601f81018813611fcb575f80fd5b80356001600160401b03811115611fe0575f80fd5b886020828401011115611ff1575f80fd5b959894975092955050506020019190565b5f60208284031215612012575f80fd5b813561116381611e87565b5f805f805f805f60e0888a031215612033575f80fd5b873561203e81611e87565b9650602088013561204e81611e87565b95506040880135945060608801359350608088013560ff81168114612071575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f806040838503121561209f575f80fd5b82356120aa81611e87565b915060208301356120ba81611e87565b809150509250929050565b6001600160a01b0391909116815260200190565b600181811c908216806120ed57607f821691505b60208210810361210b57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215612121575f80fd5b815161116381611e87565b60208082526018908201527743616c6c6572206e6f7420436f72653a3a6f776e6572282960401b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561064c5761064c61215e565b6001600160a01b03878116825286166020820152604081018590526060810184905260a0608082018190528101829052818360c08301375f81830160c090810191909152601f909201601f1916010195945050505050565b5f602082840312156121ed575f80fd5b5051919050565b8181038181111561064c5761064c61215e565b5f600182016122185761221861215e565b5060010190565b5f6020828403121561222f575f80fd5b815161ffff81168114611163575f80fd5b808202811582820484141761064c5761064c61215e565b5f8261227157634e487b7160e01b5f52601260045260245ffd5b50049056fe446562743a2043616e6e6f74207472616e7366657220746f6b656e7320646972ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9a2646970667358221220d4f080349f92ce3ecc9a9662a7cff368c76824556c4540a7d35f2a2f17f128a064736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000044bc1c218d3ee787ca222c09a5b30e090bf9621700000000000000000000000049fd0c4fb5172b20b7636b13c49fb15da52d5bd40000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce80000000000000000000000004e8781e422a5e6fa1a422d6f6c6938111446f906000000000000000000000000130541a39cfaa89c9ed8f387d479b277321d1ad400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000034b4149000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034b41490000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): KAI
Arg [1] : _symbol (string): KAI
Arg [2] : _liquidStabilityPool (address): 0x44bc1C218d3eE787Ca222C09a5B30E090bf96217
Arg [3] : _borrowerOperations (address): 0x49FD0C4fb5172b20b7636b13c49fb15dA52D5bd4
Arg [4] : metaCore_ (address): 0x8700AF942BE2A6E5566306D0eE7Bcc5a3A6E0ce8
Arg [5] : _factory (address): 0x4E8781E422a5E6fA1a422D6F6C6938111446F906
Arg [6] : _gasPool (address): 0x130541A39cfaA89c9eD8f387d479B277321D1ad4
Arg [7] : _psm (address): 0x0000000000000000000000000000000000000000
Arg [8] : _gasCompensation (uint256): 1000000000000000000
-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [2] : 00000000000000000000000044bc1c218d3ee787ca222c09a5b30e090bf96217
Arg [3] : 00000000000000000000000049fd0c4fb5172b20b7636b13c49fb15da52d5bd4
Arg [4] : 0000000000000000000000008700af942be2a6e5566306d0ee7bcc5a3a6e0ce8
Arg [5] : 0000000000000000000000004e8781e422a5e6fa1a422d6f6c6938111446f906
Arg [6] : 000000000000000000000000130541a39cfaa89c9ed8f387d479b277321d1ad4
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [10] : 4b41490000000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [12] : 4b41490000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.