Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x61012060 | 19011424 | 247 days ago | IN | 0 ETH | 0.12935403 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
AjnaProxyActions
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
Yes with 0 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.18; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { IAjnaPoolUtilsInfo } from "../../interfaces/ajna/IAjnaPoolUtilsInfo.sol"; import { IERC20Pool } from "../interfaces/pool/erc20/IERC20Pool.sol"; import { IAccountGuard } from "../../interfaces/dpm/IAccountGuard.sol"; import { IWETH } from "../../interfaces/tokens/IWETH.sol"; contract AjnaProxyActions { IAjnaPoolUtilsInfo public immutable poolInfoUtils; IERC20 public immutable ajnaToken; address public immutable WETH; address public immutable GUARD; address public immutable deployer; string public constant ajnaVersion = "Ajna_rc13"; address public ARC; using SafeERC20 for IERC20; constructor(IAjnaPoolUtilsInfo _poolInfoUtils, IERC20 _ajnaToken, address _WETH, address _GUARD) { require(address(_poolInfoUtils) != address(0), "apa/pool-info-utils-zero-address"); require(address(_ajnaToken) != address(0) || block.chainid != 1, "apa/ajna-token-zero-address"); require(_WETH != address(0), "apa/weth-zero-address"); require(_GUARD != address(0), "apa/guard-zero-address"); poolInfoUtils = _poolInfoUtils; ajnaToken = _ajnaToken; WETH = _WETH; GUARD = _GUARD; deployer = msg.sender; } /** * @dev Emitted once an Operation has completed execution * @param name Name of the operation **/ event ProxyActionsOperation(bytes32 indexed name); /** * @dev Emitted when a new position is created * @param proxyAddress The address of the newly created position proxy contract * @param protocol The name of the protocol associated with the position * @param positionType The type of position being created (e.g. borrow or earn) * @param collateralToken The address of the collateral token being used for the position * @param debtToken The address of the debt token being used for the position **/ event CreatePosition( address indexed proxyAddress, string protocol, string positionType, address collateralToken, address debtToken ); function _send(address token, uint256 amount) internal { if (token == WETH) { IWETH(WETH).withdraw(amount); payable(msg.sender).transfer(amount); } else { IERC20(token).safeTransfer(msg.sender, amount); } } function _pull(address token, uint256 amount) internal { if (token == WETH) { IWETH(WETH).deposit{ value: amount }(); } else { IERC20(token).safeTransferFrom(msg.sender, address(this), amount); } } function _stampLoan(IERC20Pool pool, bool stamploanEnabled) internal { if (stamploanEnabled) { pool.stampLoan(); } } /** * @notice Called internally to add an amount of credit at a specified price bucket. * @param pool Address of the Ajana Pool. * @param amount The maximum amount of quote token to be moved by a lender. * @param price The price the bucket to which the quote tokens will be added. * @dev price of uint (10**decimals) collateral token in debt token (10**decimals) with 3 decimal points for instance * @dev 1WBTC = 16,990.23 USDC translates to: 16990230 */ function _supplyQuote( IERC20Pool pool, uint256 amount, uint256 price ) internal returns (uint256 bucketLP, uint256 addedAmount) { address debtToken = pool.quoteTokenAddress(); _pull(debtToken, amount); uint256 index = convertPriceToIndex(price); IERC20(debtToken).forceApprove(address(pool), amount); (bucketLP, addedAmount) = pool.addQuoteToken( amount * pool.quoteTokenScale(), index, block.timestamp + 1 ); } /** * @notice Called internally to move max amount of credit from a specified price bucket to another specified price bucket. * @param pool Address of the Ajana Pool. * @param oldPrice The price of the bucket from which the quote tokens will be removed. * @param newPrice The price of the bucket to which the quote tokens will be added. */ function _moveQuote(IERC20Pool pool, uint256 oldPrice, uint256 newPrice) internal { uint256 oldIndex = convertPriceToIndex(oldPrice); pool.moveQuoteToken( type(uint256).max, oldIndex, convertPriceToIndex(newPrice), block.timestamp + 1 ); } /** * @notice Called internally to remove an amount of credit at a specified price bucket. * @param pool Address of the Ajana Pool. * @param amount The maximum amount of quote token to be moved by a lender. * @param price The price the bucket to which the quote tokens will be added. * @dev price of uint (10**decimals) collateral token in debt token (10**decimals) with 3 decimal points for instance * @dev 1WBTC = 16,990.23 USDC translates to: 16990230 */ function _withdrawQuote(IERC20Pool pool, uint256 amount, uint256 price) internal { address debtToken = pool.quoteTokenAddress(); uint256 index = convertPriceToIndex(price); uint256 withdrawnBalanceWAD; if (amount == type(uint256).max) { (withdrawnBalanceWAD, ) = pool.removeQuoteToken(type(uint256).max, index); } else { (withdrawnBalanceWAD, ) = pool.removeQuoteToken((amount * pool.quoteTokenScale()), index); } uint256 withdrawnBalance = _roundToScale(withdrawnBalanceWAD, pool.quoteTokenScale()) / pool.quoteTokenScale(); _send(debtToken, withdrawnBalance); } /** * @notice Reclaims collateral from liquidated bucket * @param pool Address of the Ajana Pool. * @param price Price of the bucket to redeem. */ function _removeCollateral( IERC20Pool pool, uint256 price ) internal returns (uint256 withdrawnBalance) { address collateralToken = pool.collateralAddress(); uint256 index = convertPriceToIndex(price); (uint256 withdrawnBalanceWAD, ) = pool.removeCollateral(type(uint256).max, index); withdrawnBalance = _roundToScale(withdrawnBalanceWAD, pool.collateralScale()) / pool.collateralScale(); _send(collateralToken, withdrawnBalance); } // BORROWER ACTIONS /** * @notice Deposit collateral * @param pool Pool address * @param collateralAmount Amount of collateral to deposit * @param price Price of the bucket * @param stamploanEnabled Whether to stamp the loan or not */ function depositCollateral( IERC20Pool pool, uint256 collateralAmount, uint256 price, bool stamploanEnabled ) public payable { address collateralToken = pool.collateralAddress(); _pull(collateralToken, collateralAmount); uint256 index = convertPriceToIndex(price); IERC20(collateralToken).forceApprove(address(pool), collateralAmount); pool.drawDebt(address(this), 0, index, collateralAmount * pool.collateralScale()); _stampLoan(pool, stamploanEnabled); emit ProxyActionsOperation("AjnaDeposit"); } /** * @notice Draw debt * @param pool Pool address * @param debtAmount Amount of debt to draw * @param price Price of the bucket */ function drawDebt(IERC20Pool pool, uint256 debtAmount, uint256 price) public { address debtToken = pool.quoteTokenAddress(); uint256 index = convertPriceToIndex(price); pool.drawDebt(address(this), debtAmount * pool.quoteTokenScale(), index, 0); _send(debtToken, debtAmount); emit ProxyActionsOperation("AjnaBorrow"); } /** * @notice Deposit collateral and draw debt * @param pool Pool address * @param debtAmount Amount of debt to draw * @param collateralAmount Amount of collateral to deposit * @param price Price of the bucket */ function depositCollateralAndDrawDebt( IERC20Pool pool, uint256 debtAmount, uint256 collateralAmount, uint256 price ) public { address debtToken = pool.quoteTokenAddress(); address collateralToken = pool.collateralAddress(); uint256 index = convertPriceToIndex(price); _pull(collateralToken, collateralAmount); IERC20(collateralToken).forceApprove(address(pool), collateralAmount); pool.drawDebt( address(this), debtAmount * pool.quoteTokenScale(), index, collateralAmount * pool.collateralScale() ); _send(debtToken, debtAmount); emit ProxyActionsOperation("AjnaDepositBorrow"); } /** * @notice Deposit collateral and draw debt * @param pool Pool address * @param debtAmount Amount of debt to borrow * @param collateralAmount Amount of collateral to deposit * @param price Price of the bucket * @param stamploanEnabled Whether to stamp the loan or not */ function depositAndDraw( IERC20Pool pool, uint256 debtAmount, uint256 collateralAmount, uint256 price, bool stamploanEnabled ) public payable { if (debtAmount > 0 && collateralAmount > 0) { depositCollateralAndDrawDebt(pool, debtAmount, collateralAmount, price); } else if (debtAmount > 0) { drawDebt(pool, debtAmount, price); } else if (collateralAmount > 0) { depositCollateral(pool, collateralAmount, price, stamploanEnabled); } } /** * @notice Repay debt * @param pool Pool address * @param amount Amount of debt to repay * @param stamploanEnabled Whether to stamp the loan or not */ function repayDebt(IERC20Pool pool, uint256 amount, bool stamploanEnabled) public payable { address debtToken = pool.quoteTokenAddress(); _pull(debtToken, amount); IERC20(debtToken).forceApprove(address(pool), amount); (, , , , , uint256 lupIndex_) = poolInfoUtils.poolPricesInfo(address(pool)); uint256 repaidAmountWAD = pool.repayDebt( address(this), amount * pool.quoteTokenScale(), 0, address(this), lupIndex_ ); _stampLoan(pool, stamploanEnabled); uint256 repaidAmount = _roundUpToScale(repaidAmountWAD, pool.quoteTokenScale()) / pool.quoteTokenScale(); uint256 leftoverBalance = amount - repaidAmount; if (leftoverBalance > 0) { _send(debtToken, leftoverBalance); } IERC20(debtToken).safeApprove(address(pool), 0); emit ProxyActionsOperation("AjnaRepay"); } /** * @notice Withdraw collateral * @param pool Pool address * @param amount Amount of collateral to withdraw */ function withdrawCollateral(IERC20Pool pool, uint256 amount) public { address collateralToken = pool.collateralAddress(); (, , , , , uint256 lupIndex_) = poolInfoUtils.poolPricesInfo(address(pool)); pool.repayDebt(address(this), 0, amount * pool.collateralScale(), address(this), lupIndex_); _send(collateralToken, amount); emit ProxyActionsOperation("AjnaWithdraw"); } /** * @notice Repay debt and withdraw collateral * @param pool Pool address * @param debtAmount Amount of debt to repay * @param collateralAmount Amount of collateral to withdraw */ function repayDebtAndWithdrawCollateral( IERC20Pool pool, uint256 debtAmount, uint256 collateralAmount ) public { address debtToken = pool.quoteTokenAddress(); address collateralToken = pool.collateralAddress(); _pull(debtToken, debtAmount); IERC20(debtToken).forceApprove(address(pool), debtAmount); (, , , , , uint256 lupIndex_) = poolInfoUtils.poolPricesInfo(address(pool)); uint256 repaidAmountWAD = pool.repayDebt( address(this), debtAmount * pool.quoteTokenScale(), collateralAmount * pool.collateralScale(), address(this), lupIndex_ ); _send(collateralToken, collateralAmount); uint256 repaidAmount = _roundUpToScale(repaidAmountWAD, pool.quoteTokenScale()) / pool.quoteTokenScale(); uint256 quoteLeftoverBalance = debtAmount - repaidAmount; if (quoteLeftoverBalance > 0) { _send(debtToken, quoteLeftoverBalance); } IERC20(debtToken).safeApprove(address(pool), 0); emit ProxyActionsOperation("AjnaRepayWithdraw"); } /** * @notice Repay debt and withdraw collateral for msg.sender * @param pool Pool address * @param debtAmount Amount of debt to repay * @param collateralAmount Amount of collateral to withdraw * @param stamploanEnabled Whether to stamp the loan or not */ function repayWithdraw( IERC20Pool pool, uint256 debtAmount, uint256 collateralAmount, bool stamploanEnabled ) external payable { if (debtAmount > 0 && collateralAmount > 0) { repayDebtAndWithdrawCollateral(pool, debtAmount, collateralAmount); } else if (debtAmount > 0) { repayDebt(pool, debtAmount, stamploanEnabled); } else if (collateralAmount > 0) { withdrawCollateral(pool, collateralAmount); } } /** * @notice Repay debt and close position for msg.sender * @param pool Pool address */ function repayAndClose(IERC20Pool pool) public payable { address collateralToken = pool.collateralAddress(); address debtToken = pool.quoteTokenAddress(); (uint256 debt, uint256 collateral, ) = poolInfoUtils.borrowerInfo(address(pool), address(this)); uint256 debtPlusBuffer = _roundUpToScale(debt, pool.quoteTokenScale()); uint256 amountDebt = debtPlusBuffer / pool.quoteTokenScale(); _pull(debtToken, amountDebt); IERC20(debtToken).forceApprove(address(pool), amountDebt); (, , , , , uint256 lupIndex_) = poolInfoUtils.poolPricesInfo(address(pool)); pool.repayDebt(address(this), debtPlusBuffer, collateral, address(this), lupIndex_); uint256 amountCollateral = collateral / pool.collateralScale(); _send(collateralToken, amountCollateral); IERC20(debtToken).safeApprove(address(pool), 0); emit ProxyActionsOperation("AjnaRepayAndClose"); } /** * @notice Open position for msg.sender * @param pool Pool address * @param debtAmount Amount of debt to borrow * @param collateralAmount Amount of collateral to deposit * @param price Price of the bucket */ function openPosition( IERC20Pool pool, uint256 debtAmount, uint256 collateralAmount, uint256 price ) public payable { emit CreatePosition( address(this), ajnaVersion, "Borrow", pool.collateralAddress(), pool.quoteTokenAddress() ); depositAndDraw(pool, debtAmount, collateralAmount, price, false); } /** * @notice Open Earn position for msg.sender * @param pool Pool address * @param depositAmount Amount of debt to borrow * @param price Price of the bucket */ function openEarnPosition(IERC20Pool pool, uint256 depositAmount, uint256 price) public payable { emit CreatePosition( address(this), ajnaVersion, "Earn", pool.collateralAddress(), pool.quoteTokenAddress() ); _validateBucketState(pool, convertPriceToIndex(price)); _supplyQuote(pool, depositAmount, price); emit ProxyActionsOperation("AjnaSupplyQuote"); } /** * @notice Called by lenders to add an amount of credit at a specified price bucket. * @param pool Address of the Ajana Pool. * @param amount The maximum amount of quote token to be moved by a lender. * @param price The price the bucket to which the quote tokens will be added. * @dev price of uint (10**decimals) collateral token in debt token (10**decimals) with 3 decimal points for instance * @dev 1WBTC = 16,990.23 USDC translates to: 16990230 */ function supplyQuote(IERC20Pool pool, uint256 amount, uint256 price) public payable { _validateBucketState(pool, convertPriceToIndex(price)); _supplyQuote(pool, amount, price); emit ProxyActionsOperation("AjnaSupplyQuote"); } /** * @notice Called by lenders to remove an amount of credit at a specified price bucket. * @param pool Address of the Ajana Pool. * @param amount The maximum amount of quote token to be moved by a lender. * @param price The price the bucket to which the quote tokens will be added. * @dev price of uint (10**decimals) collateral token in debt token (10**decimals) with 3 decimal points for instance * @dev 1WBTC = 16,990.23 USDC translates to: 16990230 */ function withdrawQuote(IERC20Pool pool, uint256 amount, uint256 price) public { _withdrawQuote(pool, amount, price); emit ProxyActionsOperation("AjnaWithdrawQuote"); } /** * @notice Called by lenders to move max amount of credit from a specified price bucket to another specified price bucket. * @param pool Address of the Ajana Pool. * @param oldPrice The price of the bucket from which the quote tokens will be removed. * @param newPrice The price of the bucket to which the quote tokens will be added. */ function moveQuote(IERC20Pool pool, uint256 oldPrice, uint256 newPrice) public { _validateBucketState(pool, convertPriceToIndex(newPrice)); _moveQuote(pool, oldPrice, newPrice); emit ProxyActionsOperation("AjnaMoveQuote"); } /** * @notice Called by lenders to move an amount of credit from a specified price bucket to another specified price bucket, * @notice whilst adding additional amount. * @param pool Address of the Ajana Pool. * @param amountToAdd The maximum amount of quote token to be moved by a lender. * @param oldPrice The price of the bucket from which the quote tokens will be removed. * @param newPrice The price of the bucket to which the quote tokens will be added. */ function supplyAndMoveQuote( IERC20Pool pool, uint256 amountToAdd, uint256 oldPrice, uint256 newPrice ) public payable { _validateBucketState(pool, convertPriceToIndex(newPrice)); _supplyQuote(pool, amountToAdd, newPrice); _validateBucketState(pool, convertPriceToIndex(newPrice)); _moveQuote(pool, oldPrice, newPrice); emit ProxyActionsOperation("AjnaSupplyAndMoveQuote"); } /** * @notice Called by lenders to move an amount of credit from a specified price bucket to another specified price bucket, * @notice whilst withdrawing additional amount. * @param pool Address of the Ajana Pool. * @param amountToWithdraw Amount of quote token to be withdrawn by a lender. * @param oldPrice The price of the bucket from which the quote tokens will be removed. * @param newPrice The price of the bucket to which the quote tokens will be added. */ function withdrawAndMoveQuote( IERC20Pool pool, uint256 amountToWithdraw, uint256 oldPrice, uint256 newPrice ) public { _withdrawQuote(pool, amountToWithdraw, oldPrice); _validateBucketState(pool, convertPriceToIndex(newPrice)); _moveQuote(pool, oldPrice, newPrice); emit ProxyActionsOperation("AjnaWithdrawAndMoveQuote"); } /** * @notice Reclaims collateral from liquidated bucket * @param pool Address of the Ajana Pool. * @param price Price of the bucket to redeem. */ function removeCollateral(IERC20Pool pool, uint256 price) public { _removeCollateral(pool, price); emit ProxyActionsOperation("AjnaRemoveCollateral"); } // VIEW FUNCTIONS /** * @notice Converts price to index * @param price price of uint (10**decimals) collateral token in debt token (10**decimals) with 18 decimal points for instance * @return index index of the bucket * @dev price of uint (10**decimals) collateral token in debt token (10**decimals) with 18 decimal points for instance * @dev 1WBTC = 16,990.23 USDC translates to: 16990230000000000000000 */ function convertPriceToIndex(uint256 price) public view returns (uint256) { return poolInfoUtils.priceToIndex(price); } /** * @dev Validates the state of a bucket in an IERC20Pool contract. * @param pool The IERC20Pool contract address. * @param bucket The index of the bucket to validate. */ function _validateBucketState(IERC20Pool pool, uint256 bucket) public view { (, , , uint256 bucketLP_, , ) = poolInfoUtils.bucketInfo(address(pool), bucket); require(bucketLP_ == 0 || bucketLP_ > 1_000_000, "apa/bucket-lps-invalid"); } /** * @notice Get the amount of quote token deposited to a specific bucket * @param pool Address of the Ajana Pool. * @param price Price of the bucket to query * @return quoteAmount Amount of quote token deposited to dpecific bucket * @dev price of uint (10**decimals) collateral token in debt token (10**decimals) with 18 decimal points for instance * @dev 1WBTC = 16,990.23 USDC translates to: 16990230000000000000000 */ function getQuoteAmount( IERC20Pool pool, uint256 price ) public view returns (uint256 quoteAmount) { uint256 index = convertPriceToIndex(price); (uint256 lpCount, ) = pool.lenderInfo(index, address(this)); quoteAmount = poolInfoUtils.lpToQuoteTokens(address(pool), lpCount, index); } /** * @notice Rounds a token amount down to the minimum amount permissible by the token scale. * @param amount_ Value to be rounded. * @param tokenScale_ Scale of the token, presented as a power of `10`. * @return scaledAmount_ Rounded value. */ function _roundToScale( uint256 amount_, uint256 tokenScale_ ) internal pure returns (uint256 scaledAmount_) { scaledAmount_ = (amount_ / tokenScale_) * tokenScale_; } /** * @notice Rounds a token amount up to the next amount permissible by the token scale. * @param amount_ Value to be rounded. * @param tokenScale_ Scale of the token, presented as a power of `10`. * @return scaledAmount_ Rounded value. */ function _roundUpToScale( uint256 amount_, uint256 tokenScale_ ) internal pure returns (uint256 scaledAmount_) { if (amount_ % tokenScale_ == 0) scaledAmount_ = amount_; else scaledAmount_ = _roundToScale(amount_, tokenScale_) + tokenScale_; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `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 (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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 (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title Pool Borrower Actions */ interface IPoolBorrowerActions { /** * @notice Called by fully collateralized borrowers to restamp the `Np to Tp ratio` of the loan (only if loan is fully collateralized and not in auction). * The reason for stamping the `Np to Tp ratio` on the loan is to provide some certainty to the borrower as to at what price they can expect to be liquidated. * This action can restamp only the loan of `msg.sender`. */ function stampLoan() external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title Pool Derived State */ interface IPoolDerivedState { /** * @notice Returns the exchange rate for a given bucket index. * @param index_ The bucket index. * @return exchangeRate_ Exchange rate of the bucket (`WAD` precision). */ function bucketExchangeRate( uint256 index_ ) external view returns (uint256 exchangeRate_); /** * @notice Returns the prefix sum of a given bucket. * @param index_ The bucket index. * @return The deposit up to given index (`WAD` precision). */ function depositUpToIndex( uint256 index_ ) external view returns (uint256); /** * @notice Returns the bucket index for a given debt amount. * @param debt_ The debt amount to calculate bucket index for (`WAD` precision). * @return Bucket index. */ function depositIndex( uint256 debt_ ) external view returns (uint256); /** * @notice Returns the total amount of quote tokens deposited in pool. * @return Total amount of deposited quote tokens (`WAD` precision). */ function depositSize() external view returns (uint256); /** * @notice Returns the meaningful actual utilization of the pool. * @return Deposit utilization (`WAD` precision). */ function depositUtilization() external view returns (uint256); /** * @notice Returns the scaling value of deposit at given index. * @param index_ Deposit index. * @return Deposit scaling (`WAD` precision). */ function depositScale( uint256 index_ ) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title Pool Errors. */ interface IPoolErrors { /**************************/ /*** Common Pool Errors ***/ /**************************/ /** * @notice Adding liquidity above current auction price. */ error AddAboveAuctionPrice(); /** * @notice The action cannot be executed on an active auction. */ error AuctionActive(); /** * @notice Attempted auction to clear doesn't meet conditions. */ error AuctionNotClearable(); /** * @notice Auction does not meet requirements to take liquidity. */ error AuctionNotTakeable(); /** * @notice Head auction should be cleared prior of executing this action. */ error AuctionNotCleared(); /** * @notice The auction price is greater than the arbed bucket price. */ error AuctionPriceGtBucketPrice(); /** * @notice Pool already initialized. */ error AlreadyInitialized(); /** * @notice Borrower is attempting to create or modify a loan such that their loan's quote token would be less than the pool's minimum debt amount. */ error AmountLTMinDebt(); /** * @notice Recipient of borrowed quote tokens doesn't match the caller of the `drawDebt` function. */ error BorrowerNotSender(); /** * @notice Borrower has a healthy over-collateralized position. */ error BorrowerOk(); /** * @notice Borrower is attempting to borrow more quote token than they have collateral for. */ error BorrowerUnderCollateralized(); /** * @notice Operation cannot be executed in the same block when bucket becomes insolvent. */ error BucketBankruptcyBlock(); /** * @notice User attempted to merge collateral from a lower price bucket into a higher price bucket. */ error CannotMergeToHigherPrice(); /** * @notice User attempted an operation which does not exceed the dust amount, or leaves behind less than the dust amount. */ error DustAmountNotExceeded(); /** * @notice Callback invoked by `flashLoan` function did not return the expected hash (see `ERC-3156` spec). */ error FlashloanCallbackFailed(); /** * @notice Balance of pool contract before flashloan is different than the balance after flashloan. */ error FlashloanIncorrectBalance(); /** * @notice Pool cannot facilitate a flashloan for the specified token address. */ error FlashloanUnavailableForToken(); /** * @notice User is attempting to move or pull more collateral than is available. */ error InsufficientCollateral(); /** * @notice Lender is attempting to move or remove more collateral they have claim to in the bucket. * @notice Lender is attempting to remove more collateral they have claim to in the bucket. * @notice Lender must have enough `LP` to claim the desired amount of quote from the bucket. */ error InsufficientLP(); /** * @notice Bucket must have more quote available in the bucket than the lender is attempting to claim. */ error InsufficientLiquidity(); /** * @notice When increasing / decreasing `LP` allowances indexes and amounts arrays parameters should have same length. */ error InvalidAllowancesInput(); /** * @notice When transferring `LP` between indices, the new index must be a valid index. */ error InvalidIndex(); /** * @notice The amount used for performed action should be greater than `0`. */ error InvalidAmount(); /** * @notice Borrower is attempting to borrow more quote token than is available before the supplied `limitIndex`. */ error LimitIndexExceeded(); /** * @notice When moving quote token `HTP` must stay below `LUP`. * @notice When removing quote token `HTP` must stay below `LUP`. */ error LUPBelowHTP(); /** * @notice From index and to index arguments to move are the same. */ error MoveToSameIndex(); /** * @notice Owner of the `LP` must have approved the new owner prior to transfer. */ error NoAllowance(); /** * @notice Actor is attempting to take or clear an inactive auction. */ error NoAuction(); /** * @notice No pool reserves are claimable. */ error NoReserves(); /** * @notice Actor is attempting to take or clear an inactive reserves auction. */ error NoReservesAuction(); /** * @notice Lender must have non-zero `LP` when attemptign to remove quote token from the pool. */ error NoClaim(); /** * @notice Borrower has no debt to liquidate. * @notice Borrower is attempting to repay when they have no outstanding debt. */ error NoDebt(); /** * @notice Actor is attempting to kick with bucket price below the `LUP`. */ error PriceBelowLUP(); /** * @notice Lender is attempting to remove quote tokens from a bucket that exists above active auction debt from top-of-book downward. */ error RemoveDepositLockedByAuctionDebt(); /** * @notice User attempted to kick off a new auction less than `2` weeks since the last auction completed. */ error ReserveAuctionTooSoon(); /** * @notice Current block timestamp has reached or exceeded a user-provided expiration. */ error TransactionExpired(); /** * @notice The address that transfer `LP` is not approved by the `LP` receiving address. */ error TransferorNotApproved(); /** * @notice Owner of the `LP` attemps to transfer `LP` to same address. */ error TransferToSameOwner(); /** * @notice The DebtToCollateral of the loan to be inserted in loans heap is zero. */ error ZeroDebtToCollateral(); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title Pool Events */ interface IPoolEvents { /*********************/ /*** Lender events ***/ /*********************/ /** * @notice Emitted when lender adds quote token to the pool. * @param lender Recipient that added quote tokens. * @param index Index at which quote tokens were added. * @param amount Amount of quote tokens added to the pool (`WAD` precision). * @param lpAwarded Amount of `LP` awarded for the deposit (`WAD` precision). * @param lup `LUP` calculated after deposit. */ event AddQuoteToken( address indexed lender, uint256 indexed index, uint256 amount, uint256 lpAwarded, uint256 lup ); /** * @notice Emitted when lender moves quote token from a bucket price to another. * @param lender Recipient that moved quote tokens. * @param from Price bucket from which quote tokens were moved. * @param to Price bucket where quote tokens were moved. * @param amount Amount of quote tokens moved (`WAD` precision). * @param lpRedeemedFrom Amount of `LP` removed from the `from` bucket (`WAD` precision). * @param lpAwardedTo Amount of `LP` credited to the `to` bucket (`WAD` precision). * @param lup `LUP` calculated after removal. */ event MoveQuoteToken( address indexed lender, uint256 indexed from, uint256 indexed to, uint256 amount, uint256 lpRedeemedFrom, uint256 lpAwardedTo, uint256 lup ); /** * @notice Emitted when lender removes quote token from the pool. * @param lender Recipient that removed quote tokens. * @param index Index at which quote tokens were removed. * @param amount Amount of quote tokens removed from the pool (`WAD` precision). * @param lpRedeemed Amount of `LP` exchanged for quote token (`WAD` precision). * @param lup `LUP` calculated after removal. */ event RemoveQuoteToken( address indexed lender, uint256 indexed index, uint256 amount, uint256 lpRedeemed, uint256 lup ); /** * @notice Emitted when lender claims collateral from a bucket. * @param claimer Recipient that claimed collateral. * @param index Index at which collateral was claimed. * @param amount The amount of collateral (`WAD` precision for `ERC20` pools, number of `NFT` tokens for `ERC721` pools) transferred to the claimer. * @param lpRedeemed Amount of `LP` exchanged for quote token (`WAD` precision). */ event RemoveCollateral( address indexed claimer, uint256 indexed index, uint256 amount, uint256 lpRedeemed ); /***********************/ /*** Borrower events ***/ /***********************/ /** * @notice Emitted when borrower repays quote tokens to the pool and/or pulls collateral from the pool. * @param borrower `msg.sender` or on behalf of sender. * @param quoteRepaid Amount of quote tokens repaid to the pool (`WAD` precision). * @param collateralPulled The amount of collateral (`WAD` precision for `ERC20` pools, number of `NFT` tokens for `ERC721` pools) transferred to the claimer. * @param lup `LUP` after repay. */ event RepayDebt( address indexed borrower, uint256 quoteRepaid, uint256 collateralPulled, uint256 lup ); /**********************/ /*** Auction events ***/ /**********************/ /** * @notice Emitted when a liquidation is initiated. * @param borrower Identifies the loan being liquidated. * @param debt Debt the liquidation will attempt to cover (`WAD` precision). * @param collateral Amount of collateral up for liquidation (`WAD` precision for `ERC20` pools, number of `NFT` tokens for `ERC721` pools). * @param bond Bond amount locked by kicker (`WAD` precision). */ event Kick( address indexed borrower, uint256 debt, uint256 collateral, uint256 bond ); /** * @notice Emitted when kickers are withdrawing funds posted as auction bonds. * @param kicker The kicker withdrawing bonds. * @param reciever The address receiving withdrawn bond amount. * @param amount The bond amount that was withdrawn (`WAD` precision). */ event BondWithdrawn( address indexed kicker, address indexed reciever, uint256 amount ); /** * @notice Emitted when an actor uses quote token to arb higher-priced deposit off the book. * @param borrower Identifies the loan being liquidated. * @param index The index of the `Highest Price Bucket` used for this take. * @param amount Amount of quote token used to purchase collateral (`WAD` precision). * @param collateral Amount of collateral purchased with quote token (`WAD` precision). * @param bondChange Impact of this take to the liquidation bond (`WAD` precision). * @param isReward `True` if kicker was rewarded with `bondChange` amount, `false` if kicker was penalized. * @dev amount / collateral implies the auction price. */ event BucketTake( address indexed borrower, uint256 index, uint256 amount, uint256 collateral, uint256 bondChange, bool isReward ); /** * @notice Emitted when `LP` are awarded to a taker or kicker in a bucket take. * @param taker Actor who invoked the bucket take. * @param kicker Actor who started the auction. * @param lpAwardedTaker Amount of `LP` awarded to the taker (`WAD` precision). * @param lpAwardedKicker Amount of `LP` awarded to the actor who started the auction (`WAD` precision). */ event BucketTakeLPAwarded( address indexed taker, address indexed kicker, uint256 lpAwardedTaker, uint256 lpAwardedKicker ); /** * @notice Emitted when an actor uses quote token outside of the book to purchase collateral under liquidation. * @param borrower Identifies the loan being liquidated. * @param amount Amount of quote token used to purchase collateral (`WAD` precision). * @param collateral Amount of collateral purchased with quote token (for `ERC20` pool, `WAD` precision) or number of `NFT`s purchased (for `ERC721` pool). * @param bondChange Impact of this take to the liquidation bond (`WAD` precision). * @param isReward `True` if kicker was rewarded with `bondChange` amount, `false` if kicker was penalized. * @dev amount / collateral implies the auction price. */ event Take( address indexed borrower, uint256 amount, uint256 collateral, uint256 bondChange, bool isReward ); /** * @notice Emitted when an actor settles debt in a completed liquidation * @param borrower Identifies the loan under liquidation. * @param settledDebt Amount of pool debt settled in this transaction (`WAD` precision). * @dev When `amountRemaining_ == 0`, the auction has been completed cleared and removed from the queue. */ event Settle( address indexed borrower, uint256 settledDebt ); /** * @notice Emitted when auction is completed. * @param borrower Address of borrower that exits auction. * @param collateral Borrower's remaining collateral when auction completed (`WAD` precision). */ event AuctionSettle( address indexed borrower, uint256 collateral ); /** * @notice Emitted when `NFT` auction is completed. * @param borrower Address of borrower that exits auction. * @param collateral Borrower's remaining collateral when auction completed. * @param lp Amount of `LP` given to the borrower to compensate fractional collateral (if any, `WAD` precision). * @param index Index of the bucket with `LP` to compensate fractional collateral. */ event AuctionNFTSettle( address indexed borrower, uint256 collateral, uint256 lp, uint256 index ); /** * @notice Emitted when a `Claimaible Reserve Auction` is started. * @param claimableReservesRemaining Amount of claimable reserves which has not yet been taken (`WAD` precision). * @param auctionPrice Current price at which `1` quote token may be purchased, denominated in `Ajna`. * @param currentBurnEpoch Current burn epoch. */ event KickReserveAuction( uint256 claimableReservesRemaining, uint256 auctionPrice, uint256 currentBurnEpoch ); /** * @notice Emitted when a `Claimaible Reserve Auction` is taken. * @param claimableReservesRemaining Amount of claimable reserves which has not yet been taken (`WAD` precision). * @param auctionPrice Current price at which `1` quote token may be purchased, denominated in `Ajna`. * @param currentBurnEpoch Current burn epoch. */ event ReserveAuction( uint256 claimableReservesRemaining, uint256 auctionPrice, uint256 currentBurnEpoch ); /**************************/ /*** LP transfer events ***/ /**************************/ /** * @notice Emitted when owner increase the `LP` allowance of a spender at specified indexes with specified amounts. * @param owner `LP` owner. * @param spender Address approved to transfer `LP`. * @param indexes Bucket indexes of `LP` approved. * @param amounts `LP` amounts added (ordered by indexes, `WAD` precision). */ event IncreaseLPAllowance( address indexed owner, address indexed spender, uint256[] indexes, uint256[] amounts ); /** * @notice Emitted when owner decrease the `LP` allowance of a spender at specified indexes with specified amounts. * @param owner `LP` owner. * @param spender Address approved to transfer `LP`. * @param indexes Bucket indexes of `LP` approved. * @param amounts `LP` amounts removed (ordered by indexes, `WAD` precision). */ event DecreaseLPAllowance( address indexed owner, address indexed spender, uint256[] indexes, uint256[] amounts ); /** * @notice Emitted when lender removes the allowance of a spender for their `LP`. * @param owner `LP` owner. * @param spender Address that is having it's allowance revoked. * @param indexes List of bucket index to remove the allowance from. */ event RevokeLPAllowance( address indexed owner, address indexed spender, uint256[] indexes ); /** * @notice Emitted when lender whitelists addresses to accept `LP` from. * @param lender Recipient that approves new owner for `LP`. * @param transferors List of addresses that can transfer `LP` to lender. */ event ApproveLPTransferors( address indexed lender, address[] transferors ); /** * @notice Emitted when lender removes addresses from the `LP` transferors whitelist. * @param lender Recipient that approves new owner for `LP`. * @param transferors List of addresses that won't be able to transfer `LP` to lender anymore. */ event RevokeLPTransferors( address indexed lender, address[] transferors ); /** * @notice Emitted when a lender transfers their `LP` to a different address. * @dev Used by `PositionManager.memorializePositions()`. * @param owner The original owner address of the position. * @param newOwner The new owner address of the position. * @param indexes Array of price bucket indexes at which `LP` were transferred. * @param lp Amount of `LP` transferred (`WAD` precision). */ event TransferLP( address owner, address newOwner, uint256[] indexes, uint256 lp ); /**************************/ /*** Pool common events ***/ /**************************/ /** * @notice Emitted when `LP` are forfeited as a result of the bucket losing all assets. * @param index The index of the bucket. * @param lpForfeited Amount of `LP` forfeited by lenders (`WAD` precision). */ event BucketBankruptcy( uint256 indexed index, uint256 lpForfeited ); /** * @notice Emitted when a flashloan is taken from pool. * @param receiver The address receiving the flashloan. * @param token The address of token flashloaned from pool. * @param amount The amount of tokens flashloaned from pool (token precision). */ event Flashloan( address indexed receiver, address indexed token, uint256 amount ); /** * @notice Emitted when a loan `Np to Tp ratio` is restamped. * @param borrower Identifies the loan to update the `Np to Tp ratio`. */ event LoanStamped( address indexed borrower ); /** * @notice Emitted when pool interest rate is reset. This happens when `interest rate > 10%` and `debtEma < 5%` of `depositEma` * @param oldRate Old pool interest rate. * @param newRate New pool interest rate. */ event ResetInterestRate( uint256 oldRate, uint256 newRate ); /** * @notice Emitted when pool interest rate is updated. * @param oldRate Old pool interest rate. * @param newRate New pool interest rate. */ event UpdateInterestRate( uint256 oldRate, uint256 newRate ); /** * @notice Emitted when interest accural or update interest overflows. */ event InterestUpdateFailure(); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title Pool Immutables */ interface IPoolImmutables { /** * @notice Returns the type of the pool (`0` for `ERC20`, `1` for `ERC721`). */ function poolType() external pure returns (uint8); /** * @notice Returns the address of the pool's collateral token. */ function collateralAddress() external pure returns (address); /** * @notice Returns the address of the pool's quote token. */ function quoteTokenAddress() external pure returns (address); /** * @notice Returns the `quoteTokenScale` state variable. * @notice Token scale is also the minimum amount a lender may have in a bucket (dust amount). * @return The precision of the quote `ERC20` token based on decimals. */ function quoteTokenScale() external pure returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title Pool Kicker Actions */ interface IPoolKickerActions { /********************/ /*** Liquidations ***/ /********************/ /** * @notice Called by actors to initiate a liquidation. * @param borrower_ Identifies the loan to liquidate. * @param npLimitIndex_ Index of the lower bound of `NP` tolerated when kicking the auction. */ function kick( address borrower_, uint256 npLimitIndex_ ) external; /** * @notice Called by lenders to liquidate the top loan. * @param index_ The deposit index to use for kicking the top loan. * @param npLimitIndex_ Index of the lower bound of `NP` tolerated when kicking the auction. */ function lenderKick( uint256 index_, uint256 npLimitIndex_ ) external; /** * @notice Called by kickers to withdraw their auction bonds (the amount of quote tokens that are not locked in active auctions). * @param recipient_ Address to receive claimed bonds amount. * @param maxAmount_ The max amount to withdraw from auction bonds (`WAD` precision). Constrained by claimable amounts and liquidity. * @return withdrawnAmount_ The amount withdrawn (`WAD` precision). */ function withdrawBonds( address recipient_, uint256 maxAmount_ ) external returns (uint256 withdrawnAmount_); /***********************/ /*** Reserve Auction ***/ /***********************/ /** * @notice Called by actor to start a `Claimable Reserve Auction` (`CRA`). */ function kickReserveAuction() external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title Pool Lender Actions */ interface IPoolLenderActions { /*********************************************/ /*** Quote/collateral management functions ***/ /*********************************************/ /** * @notice Called by lenders to add an amount of credit at a specified price bucket. * @param amount_ The amount of quote token to be added by a lender (`WAD` precision). * @param index_ The index of the bucket to which the quote tokens will be added. * @param expiry_ Timestamp after which this transaction will revert, preventing inclusion in a block with unfavorable price. * @return bucketLP_ The amount of `LP` changed for the added quote tokens (`WAD` precision). * @return addedAmount_ The amount of quote token added (`WAD` precision). */ function addQuoteToken( uint256 amount_, uint256 index_, uint256 expiry_ ) external returns (uint256 bucketLP_, uint256 addedAmount_); /** * @notice Called by lenders to move an amount of credit from a specified price bucket to another specified price bucket. * @param maxAmount_ The maximum amount of quote token to be moved by a lender (`WAD` precision). * @param fromIndex_ The bucket index from which the quote tokens will be removed. * @param toIndex_ The bucket index to which the quote tokens will be added. * @param expiry_ Timestamp after which this transaction will revert, preventing inclusion in a block with unfavorable price. * @return fromBucketLP_ The amount of `LP` moved out from bucket (`WAD` precision). * @return toBucketLP_ The amount of `LP` moved to destination bucket (`WAD` precision). * @return movedAmount_ The amount of quote token moved (`WAD` precision). */ function moveQuoteToken( uint256 maxAmount_, uint256 fromIndex_, uint256 toIndex_, uint256 expiry_ ) external returns (uint256 fromBucketLP_, uint256 toBucketLP_, uint256 movedAmount_); /** * @notice Called by lenders to claim collateral from a price bucket. * @param maxAmount_ The amount of collateral (`WAD` precision for `ERC20` pools, number of `NFT` tokens for `ERC721` pools) to claim. * @param index_ The bucket index from which collateral will be removed. * @return removedAmount_ The amount of collateral removed (`WAD` precision). * @return redeemedLP_ The amount of `LP` used for removing collateral amount (`WAD` precision). */ function removeCollateral( uint256 maxAmount_, uint256 index_ ) external returns (uint256 removedAmount_, uint256 redeemedLP_); /** * @notice Called by lenders to remove an amount of credit at a specified price bucket. * @param maxAmount_ The max amount of quote token to be removed by a lender (`WAD` precision). * @param index_ The bucket index from which quote tokens will be removed. * @return removedAmount_ The amount of quote token removed (`WAD` precision). * @return redeemedLP_ The amount of `LP` used for removing quote tokens amount (`WAD` precision). */ function removeQuoteToken( uint256 maxAmount_, uint256 index_ ) external returns (uint256 removedAmount_, uint256 redeemedLP_); /********************************/ /*** Interest update function ***/ /********************************/ /** * @notice Called by actors to update pool interest rate (can be updated only once in a `12` hours period of time). */ function updateInterest() external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title Pool `LP` Actions */ interface IPoolLPActions { /** * @notice Called by `LP` owners to approve transfer of an amount of `LP` to a new owner. * @dev Intended for use by the `PositionManager` contract. * @param spender_ The new owner of the `LP`. * @param indexes_ Bucket indexes from where `LP` are transferred. * @param amounts_ The amounts of `LP` approved to transfer (`WAD` precision). */ function increaseLPAllowance( address spender_, uint256[] calldata indexes_, uint256[] calldata amounts_ ) external; /** * @notice Called by `LP` owners to decrease the amount of `LP` that can be spend by a new owner. * @dev Intended for use by the `PositionManager` contract. * @param spender_ The new owner of the `LP`. * @param indexes_ Bucket indexes from where `LP` are transferred. * @param amounts_ The amounts of `LP` disapproved to transfer (`WAD` precision). */ function decreaseLPAllowance( address spender_, uint256[] calldata indexes_, uint256[] calldata amounts_ ) external; /** * @notice Called by `LP` owners to decrease the amount of `LP` that can be spend by a new owner. * @param spender_ Address that is having it's allowance revoked. * @param indexes_ List of bucket index to remove the allowance from. */ function revokeLPAllowance( address spender_, uint256[] calldata indexes_ ) external; /** * @notice Called by `LP` owners to allow addresses that can transfer LP. * @dev Intended for use by the `PositionManager` contract. * @param transferors_ Addresses that are allowed to transfer `LP` to new owner. */ function approveLPTransferors( address[] calldata transferors_ ) external; /** * @notice Called by `LP` owners to revoke addresses that can transfer `LP`. * @dev Intended for use by the `PositionManager` contract. * @param transferors_ Addresses that are revoked to transfer `LP` to new owner. */ function revokeLPTransferors( address[] calldata transferors_ ) external; /** * @notice Called by `LP` owners to transfers their `LP` to a different address. `approveLpOwnership` needs to be run first. * @dev Used by `PositionManager.memorializePositions()`. * @param owner_ The original owner address of the position. * @param newOwner_ The new owner address of the position. * @param indexes_ Array of price buckets index at which `LP` were moved. */ function transferLP( address owner_, address newOwner_, uint256[] calldata indexes_ ) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title Pool Settler Actions */ interface IPoolSettlerActions { /** * @notice Called by actors to settle an amount of debt in a completed liquidation. * @param borrowerAddress_ Address of the auctioned borrower. * @param maxDepth_ Measured from `HPB`, maximum number of buckets deep to settle debt. * @return collateralSettled_ Amount of collateral settled. * @return isBorrowerSettled_ True if all borrower's debt is settled. * @dev `maxDepth_` is used to prevent unbounded iteration clearing large liquidations. */ function settle( address borrowerAddress_, uint256 maxDepth_ ) external returns (uint256 collateralSettled_, bool isBorrowerSettled_); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title Pool State */ interface IPoolState { /** * @notice Returns details of an auction for a given borrower address. * @param borrower_ Address of the borrower that is liquidated. * @return kicker_ Address of the kicker that is kicking the auction. * @return bondFactor_ The factor used for calculating bond size. * @return bondSize_ The bond amount in quote token terms. * @return kickTime_ Time the liquidation was initiated. * @return referencePrice_ Price used to determine auction start price. * @return neutralPrice_ `Neutral Price` of auction. * @return debtToCollateral_ Borrower debt to collateral, which is used in BPF for kicker's reward calculation. * @return head_ Address of the head auction. * @return next_ Address of the next auction in queue. * @return prev_ Address of the prev auction in queue. */ function auctionInfo(address borrower_) external view returns ( address kicker_, uint256 bondFactor_, uint256 bondSize_, uint256 kickTime_, uint256 referencePrice_, uint256 neutralPrice_, uint256 debtToCollateral_, address head_, address next_, address prev_ ); /** * @notice Returns pool related debt values. * @return debt_ Current amount of debt owed by borrowers in pool. * @return accruedDebt_ Debt owed by borrowers based on last inflator snapshot. * @return debtInAuction_ Total amount of debt in auction. * @return t0Debt2ToCollateral_ t0debt accross all borrowers divided by their collateral, used in determining a collateralization weighted debt. */ function debtInfo() external view returns ( uint256 debt_, uint256 accruedDebt_, uint256 debtInAuction_, uint256 t0Debt2ToCollateral_ ); /** * @notice Mapping of borrower addresses to `Borrower` structs. * @dev NOTE: Cannot use appended underscore syntax for return params since struct is used. * @param borrower_ Address of the borrower. * @return t0Debt_ Amount of debt borrower would have had if their loan was the first debt drawn from the pool. * @return collateral_ Amount of collateral that the borrower has deposited, in collateral token. * @return npTpRatio_ Np to Tp ratio of borrower at the time of last borrow or pull collateral. */ function borrowerInfo(address borrower_) external view returns ( uint256 t0Debt_, uint256 collateral_, uint256 npTpRatio_ ); /** * @notice Mapping of buckets indexes to `Bucket` structs. * @dev NOTE: Cannot use appended underscore syntax for return params since struct is used. * @param index_ Bucket index. * @return lpAccumulator_ Amount of `LP` accumulated in current bucket. * @return availableCollateral_ Amount of collateral available in current bucket. * @return bankruptcyTime_ Timestamp when bucket become insolvent, `0` if healthy. * @return bucketDeposit_ Amount of quote tokens in bucket. * @return bucketScale_ Bucket multiplier. */ function bucketInfo(uint256 index_) external view returns ( uint256 lpAccumulator_, uint256 availableCollateral_, uint256 bankruptcyTime_, uint256 bucketDeposit_, uint256 bucketScale_ ); /** * @notice Mapping of burnEventEpoch to `BurnEvent` structs. * @dev Reserve auctions correspond to burn events. * @param burnEventEpoch_ Id of the current reserve auction. * @return burnBlock_ Block in which a reserve auction started. * @return totalInterest_ Total interest as of the reserve auction. * @return totalBurned_ Total ajna tokens burned as of the reserve auction. */ function burnInfo(uint256 burnEventEpoch_) external view returns (uint256, uint256, uint256); /** * @notice Returns the latest `burnEventEpoch` of reserve auctions. * @dev If a reserve auction is active, it refers to the current reserve auction. If no reserve auction is active, it refers to the last reserve auction. * @return Current `burnEventEpoch`. */ function currentBurnEpoch() external view returns (uint256); /** * @notice Returns information about the pool `EMA (Exponential Moving Average)` variables. * @return debtColEma_ Debt squared to collateral Exponential, numerator to `TU` calculation. * @return lupt0DebtEma_ Exponential of `LUP * t0 debt`, denominator to `TU` calculation * @return debtEma_ Exponential debt moving average. * @return depositEma_ sample of meaningful deposit Exponential, denominator to `MAU` calculation. */ function emasInfo() external view returns ( uint256 debtColEma_, uint256 lupt0DebtEma_, uint256 debtEma_, uint256 depositEma_ ); /** * @notice Returns information about pool inflator. * @return inflator_ Pool inflator value. * @return lastUpdate_ The timestamp of the last `inflator` update. */ function inflatorInfo() external view returns ( uint256 inflator_, uint256 lastUpdate_ ); /** * @notice Returns information about pool interest rate. * @return interestRate_ Current interest rate in pool. * @return interestRateUpdate_ The timestamp of the last interest rate update. */ function interestRateInfo() external view returns ( uint256 interestRate_, uint256 interestRateUpdate_ ); /** * @notice Returns details about kicker balances. * @param kicker_ The address of the kicker to retrieved info for. * @return claimable_ Amount of quote token kicker can claim / withdraw from pool at any time. * @return locked_ Amount of quote token kicker locked in auctions (as bonds). */ function kickerInfo(address kicker_) external view returns ( uint256 claimable_, uint256 locked_ ); /** * @notice Mapping of buckets indexes and owner addresses to `Lender` structs. * @param index_ Bucket index. * @param lender_ Address of the liquidity provider. * @return lpBalance_ Amount of `LP` owner has in current bucket. * @return depositTime_ Time the user last deposited quote token. */ function lenderInfo( uint256 index_, address lender_ ) external view returns ( uint256 lpBalance_, uint256 depositTime_ ); /** * @notice Return the `LP` allowance a `LP` owner provided to a spender. * @param index_ Bucket index. * @param spender_ Address of the `LP` spender. * @param owner_ The initial owner of the `LP`. * @return allowance_ Amount of `LP` spender can utilize. */ function lpAllowance( uint256 index_, address spender_, address owner_ ) external view returns (uint256 allowance_); /** * @notice Returns information about a loan in the pool. * @param loanId_ Loan's id within loan heap. Max loan is position `1`. * @return borrower_ Borrower address at the given position. * @return t0DebtToCollateral_ Borrower t0 debt to collateral. */ function loanInfo( uint256 loanId_ ) external view returns ( address borrower_, uint256 t0DebtToCollateral_ ); /** * @notice Returns information about pool loans. * @return maxBorrower_ Borrower address with highest t0 debt to collateral. * @return maxT0DebtToCollateral_ Highest t0 debt to collateral in pool. * @return noOfLoans_ Total number of loans. */ function loansInfo() external view returns ( address maxBorrower_, uint256 maxT0DebtToCollateral_, uint256 noOfLoans_ ); /** * @notice Returns information about pool reserves. * @return liquidationBondEscrowed_ Amount of liquidation bond across all liquidators. * @return reserveAuctionUnclaimed_ Amount of claimable reserves which has not been taken in the `Claimable Reserve Auction`. * @return reserveAuctionKicked_ Time a `Claimable Reserve Auction` was last kicked. * @return lastKickedReserves_ Amount of reserves upon last kick, used to calculate price. * @return totalInterestEarned_ Total interest earned by all lenders in the pool */ function reservesInfo() external view returns ( uint256 liquidationBondEscrowed_, uint256 reserveAuctionUnclaimed_, uint256 reserveAuctionKicked_, uint256 lastKickedReserves_, uint256 totalInterestEarned_ ); /** * @notice Returns the `pledgedCollateral` state variable. * @return The total pledged collateral in the system, in WAD units. */ function pledgedCollateral() external view returns (uint256); /** * @notice Returns the total number of active auctions in pool. * @return totalAuctions_ Number of active auctions. */ function totalAuctionsInPool() external view returns (uint256); /** * @notice Returns the `t0Debt` state variable. * @dev This value should be multiplied by inflator in order to calculate current debt of the pool. * @return The total `t0Debt` in the system, in `WAD` units. */ function totalT0Debt() external view returns (uint256); /** * @notice Returns the `t0DebtInAuction` state variable. * @dev This value should be multiplied by inflator in order to calculate current debt in auction of the pool. * @return The total `t0DebtInAuction` in the system, in `WAD` units. */ function totalT0DebtInAuction() external view returns (uint256); /** * @notice Mapping of addresses that can transfer `LP` to a given lender. * @param lender_ Lender that receives `LP`. * @param transferor_ Transferor that transfers `LP`. * @return True if the transferor is approved by lender. */ function approvedTransferors( address lender_, address transferor_ ) external view returns (bool); } /*********************/ /*** State Structs ***/ /*********************/ /******************/ /*** Pool State ***/ /******************/ /// @dev Struct holding inflator state. struct InflatorState { uint208 inflator; // [WAD] pool's inflator uint48 inflatorUpdate; // [SEC] last time pool's inflator was updated } /// @dev Struct holding pool interest state. struct InterestState { uint208 interestRate; // [WAD] pool's interest rate uint48 interestRateUpdate; // [SEC] last time pool's interest rate was updated (not before 12 hours passed) uint256 debt; // [WAD] previous update's debt uint256 meaningfulDeposit; // [WAD] previous update's meaningfulDeposit uint256 t0Debt2ToCollateral; // [WAD] utilization weight accumulator, tracks debt and collateral relationship accross borrowers uint256 debtCol; // [WAD] previous debt squared to collateral uint256 lupt0Debt; // [WAD] previous LUP * t0 debt } /// @dev Struct holding pool EMAs state. struct EmaState { uint256 debtEma; // [WAD] sample of debt EMA, numerator to MAU calculation uint256 depositEma; // [WAD] sample of meaningful deposit EMA, denominator to MAU calculation uint256 debtColEma; // [WAD] debt squared to collateral EMA, numerator to TU calculation uint256 lupt0DebtEma; // [WAD] EMA of LUP * t0 debt, denominator to TU calculation uint256 emaUpdate; // [SEC] last time pool's EMAs were updated } /// @dev Struct holding pool balances state. struct PoolBalancesState { uint256 pledgedCollateral; // [WAD] total collateral pledged in pool uint256 t0DebtInAuction; // [WAD] Total debt in auction used to restrict LPB holder from withdrawing uint256 t0Debt; // [WAD] Pool debt as if the whole amount was incurred upon the first loan } /// @dev Struct holding pool params (in memory only). struct PoolState { uint8 poolType; // pool type, can be ERC20 or ERC721 uint256 t0Debt; // [WAD] t0 debt in pool uint256 t0DebtInAuction; // [WAD] t0 debt in auction within pool uint256 debt; // [WAD] total debt in pool, accrued in current block uint256 collateral; // [WAD] total collateral pledged in pool uint256 inflator; // [WAD] current pool inflator bool isNewInterestAccrued; // true if new interest already accrued in current block uint256 rate; // [WAD] pool's current interest rate uint256 quoteTokenScale; // [WAD] quote token scale of the pool. Same as quote token dust. } /*********************/ /*** Buckets State ***/ /*********************/ /// @dev Struct holding lender state. struct Lender { uint256 lps; // [WAD] Lender LP accumulator uint256 depositTime; // timestamp of last deposit } /// @dev Struct holding bucket state. struct Bucket { uint256 lps; // [WAD] Bucket LP accumulator uint256 collateral; // [WAD] Available collateral tokens deposited in the bucket uint256 bankruptcyTime; // Timestamp when bucket become insolvent, 0 if healthy mapping(address => Lender) lenders; // lender address to Lender struct mapping } /**********************/ /*** Deposits State ***/ /**********************/ /// @dev Struct holding deposits (Fenwick) values and scaling. struct DepositsState { uint256[8193] values; // Array of values in the FenwickTree. uint256[8193] scaling; // Array of values which scale (multiply) the FenwickTree accross indexes. } /*******************/ /*** Loans State ***/ /*******************/ /// @dev Struct holding loans state. struct LoansState { Loan[] loans; mapping (address => uint) indices; // borrower address => loan index mapping mapping (address => Borrower) borrowers; // borrower address => Borrower struct mapping } /// @dev Struct holding loan state. struct Loan { address borrower; // borrower address uint96 t0DebtToCollateral; // [WAD] Borrower t0 debt to collateral. } /// @dev Struct holding borrower state. struct Borrower { uint256 t0Debt; // [WAD] Borrower debt time-adjusted as if it was incurred upon first loan of pool. uint256 collateral; // [WAD] Collateral deposited by borrower. uint256 npTpRatio; // [WAD] Np to Tp ratio at the time of last borrow or pull collateral. } /**********************/ /*** Auctions State ***/ /**********************/ /// @dev Struct holding pool auctions state. struct AuctionsState { uint96 noOfAuctions; // total number of auctions in pool address head; // first address in auction queue address tail; // last address in auction queue uint256 totalBondEscrowed; // [WAD] total amount of quote token posted as auction kick bonds mapping(address => Liquidation) liquidations; // mapping of borrower address and auction details mapping(address => Kicker) kickers; // mapping of kicker address and kicker balances } /// @dev Struct holding liquidation state. struct Liquidation { address kicker; // address that initiated liquidation uint96 bondFactor; // [WAD] bond factor used to start liquidation uint96 kickTime; // timestamp when liquidation was started address prev; // previous liquidated borrower in auctions queue uint96 referencePrice; // [WAD] used to calculate auction start price address next; // next liquidated borrower in auctions queue uint160 bondSize; // [WAD] liquidation bond size uint96 neutralPrice; // [WAD] Neutral Price when liquidation was started uint256 debtToCollateral; // [WAD] Borrower debt to collateral, which is used in BPF for kicker's reward calculation uint256 t0ReserveSettleAmount; // [WAD] Amount of t0Debt that could be settled via reserves in this auction } /// @dev Struct holding kicker state. struct Kicker { uint256 claimable; // [WAD] kicker's claimable balance uint256 locked; // [WAD] kicker's balance of tokens locked in auction bonds } /******************************/ /*** Reserve Auctions State ***/ /******************************/ /// @dev Struct holding reserve auction state. struct ReserveAuctionState { uint256 kicked; // Time a Claimable Reserve Auction was last kicked. uint256 lastKickedReserves; // [WAD] Amount of reserves upon last kick, used to calculate price. uint256 unclaimed; // [WAD] Amount of claimable reserves which has not been taken in the Claimable Reserve Auction. uint256 latestBurnEventEpoch; // Latest burn event epoch. uint256 totalAjnaBurned; // [WAD] Total ajna burned in the pool. uint256 totalInterestEarned; // [WAD] Total interest earned by all lenders in the pool. mapping (uint256 => BurnEvent) burnEvents; // Mapping burnEventEpoch => BurnEvent. } /// @dev Struct holding burn event state. struct BurnEvent { uint256 timestamp; // time at which the burn event occured uint256 totalInterest; // [WAD] current pool interest accumulator `PoolCommons.accrueInterest().newInterest` uint256 totalBurned; // [WAD] burn amount accumulator }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title Pool Taker Actions */ interface IPoolTakerActions { /** * @notice Called by actors to use quote token to arb higher-priced deposit off the book. * @param borrowerAddress_ Address of the borower take is being called upon. * @param depositTake_ If `true` then the take will happen at an auction price equal with bucket price. Auction price is used otherwise. * @param index_ Index of a bucket, likely the `HPB`, in which collateral will be deposited. */ function bucketTake( address borrowerAddress_, bool depositTake_, uint256 index_ ) external; /** * @notice Called by actors to purchase collateral from the auction in exchange for quote token. * @param borrowerAddress_ Address of the borower take is being called upon. * @param maxAmount_ Max amount of collateral that will be taken from the auction (`WAD` precision for `ERC20` pools, max number of `NFT`s for `ERC721` pools). * @param callee_ Identifies where collateral should be sent and where quote token should be obtained. * @param data_ If provided, take will assume the callee implements `IERC*Taker`. Take will send collateral to * callee before passing this data to `IERC*Taker.atomicSwapCallback`. If not provided, * the callback function will not be invoked. * @return collateralTaken_ Amount of collateral taken from the auction (`WAD` precision for `ERC20` pools, max number of `NFT`s for `ERC721` pools). */ function take( address borrowerAddress_, uint256 maxAmount_, address callee_, bytes calldata data_ ) external returns (uint256 collateralTaken_); /***********************/ /*** Reserve Auction ***/ /***********************/ /** * @notice Purchases claimable reserves during a `CRA` using `Ajna` token. * @param maxAmount_ Maximum amount of quote token to purchase at the current auction price (`WAD` precision). * @return amount_ Actual amount of reserves taken (`WAD` precision). */ function takeReserves( uint256 maxAmount_ ) external returns (uint256 amount_); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; import { IPool } from '../IPool.sol'; import { IERC20PoolBorrowerActions } from './IERC20PoolBorrowerActions.sol'; import { IERC20PoolLenderActions } from './IERC20PoolLenderActions.sol'; import { IERC20PoolImmutables } from './IERC20PoolImmutables.sol'; import { IERC20PoolEvents } from './IERC20PoolEvents.sol'; /** * @title ERC20 Pool */ interface IERC20Pool is IPool, IERC20PoolLenderActions, IERC20PoolBorrowerActions, IERC20PoolImmutables, IERC20PoolEvents { /** * @notice Initializes a new pool, setting initial state variables. * @param rate_ Initial interest rate of the pool (min accepted value 1%, max accepted value 10%). */ function initialize(uint256 rate_) external; /** * @notice Returns the minimum amount of collateral an actor may have in a bucket. * @param bucketIndex_ The bucket index for which the dust limit is desired, or `0` for pledged collateral. * @return The dust limit for `bucketIndex_`. */ function bucketCollateralDust( uint256 bucketIndex_ ) external pure returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title ERC20 Pool Borrower Actions */ interface IERC20PoolBorrowerActions { /** * @notice Called by borrowers to add collateral to the pool and/or borrow quote from the pool. * @dev Can be called by borrowers with either `0` `amountToBorrow_` or `0` `collateralToPledge_`, if borrower only wants to take a single action. * @param borrowerAddress_ The borrower to whom collateral was pledged, and/or debt was drawn for. * @param amountToBorrow_ The amount of quote tokens to borrow (`WAD` precision). * @param limitIndex_ Lower bound of `LUP` change (if any) that the borrower will tolerate from a creating or modifying position. * @param collateralToPledge_ The amount of collateral to be added to the pool (`WAD` precision). */ function drawDebt( address borrowerAddress_, uint256 amountToBorrow_, uint256 limitIndex_, uint256 collateralToPledge_ ) external; /** * @notice Called by borrowers to repay borrowed quote to the pool, and/or pull collateral form the pool. * @dev Can be called by borrowers with either `0` `maxQuoteTokenAmountToRepay_` or `0` `collateralAmountToPull_`, if borrower only wants to take a single action. * @param borrowerAddress_ The borrower whose loan is being interacted with. * @param maxQuoteTokenAmountToRepay_ The max amount of quote tokens to repay (`WAD` precision). * @param collateralAmountToPull_ The max amount of collateral to be puled from the pool (`WAD` precision). * @param recipient_ The address to receive amount of pulled collateral. * @param limitIndex_ Ensures `LUP` has not moved far from state when borrower pulls collateral. * @return amountRepaid_ The amount of quote token repaid (`WAD` precision). */ function repayDebt( address borrowerAddress_, uint256 maxQuoteTokenAmountToRepay_, uint256 collateralAmountToPull_, address recipient_, uint256 limitIndex_ ) external returns (uint256 amountRepaid_); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title ERC20 Pool Events */ interface IERC20PoolEvents { /** * @notice Emitted when actor adds claimable collateral to a bucket. * @param actor Recipient that added collateral. * @param index Index at which collateral were added. * @param amount Amount of collateral added to the pool (`WAD` precision). * @param lpAwarded Amount of `LP` awarded for the deposit (`WAD` precision). */ event AddCollateral( address indexed actor, uint256 indexed index, uint256 amount, uint256 lpAwarded ); /** * @notice Emitted when borrower draws debt from the pool, or adds collateral to the pool. * @param borrower The borrower to whom collateral was pledged, and/or debt was drawn for. * @param amountBorrowed Amount of quote tokens borrowed from the pool (`WAD` precision). * @param collateralPledged Amount of collateral locked in the pool (`WAD` precision). * @param lup `LUP` after borrow. */ event DrawDebt( address indexed borrower, uint256 amountBorrowed, uint256 collateralPledged, uint256 lup ); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title ERC20 Pool Immutables */ interface IERC20PoolImmutables { /** * @notice Returns the `collateralScale` immutable. * @return The precision of the collateral `ERC20` token based on decimals. */ function collateralScale() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; /** * @title ERC20 Pool Lender Actions */ interface IERC20PoolLenderActions { /** * @notice Deposit claimable collateral into a specified bucket. * @param amountToAdd_ Amount of collateral to deposit (`WAD` precision). * @param index_ The bucket index to which collateral will be deposited. * @param expiry_ Timestamp after which this transaction will revert, preventing inclusion in a block with unfavorable price. * @return bucketLP_ The amount of `LP` awarded for the added collateral (`WAD` precision). */ function addCollateral( uint256 amountToAdd_, uint256 index_, uint256 expiry_ ) external returns (uint256 bucketLP_); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; 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 (token precision). * @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 `ERC3156FlashBorrower.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.18; import { IERC3156FlashBorrower } from "./IERC3156FlashBorrower.sol"; interface IERC3156FlashLender { /** * @dev The amount of currency available to be lent. * @param token_ The loan currency. * @return The amount of `token` that can be borrowed (token precision). */ function maxFlashLoan( address token_ ) external view returns (uint256); /** * @dev The fee to be charged for a given loan. * @param token_ The loan currency. * @param amount_ The amount of tokens lent (token precision). * @return The amount of `token` to be charged for the loan (token precision), on top of the returned principal . */ function flashFee( address token_, uint256 amount_ ) external view returns (uint256); /** * @dev Initiate a flash loan. * @param receiver_ The receiver of the tokens in the loan, and the receiver of the callback. * @param token_ The loan currency. * @param amount_ The amount of tokens lent (token precision). * @param data_ Arbitrary data structure, intended to contain user-defined parameters. * @return `True` when successful flashloan, `false` otherwise. */ function flashLoan( IERC3156FlashBorrower receiver_, address token_, uint256 amount_, bytes calldata data_ ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.18; import { IPoolBorrowerActions } from './commons/IPoolBorrowerActions.sol'; import { IPoolLPActions } from './commons/IPoolLPActions.sol'; import { IPoolLenderActions } from './commons/IPoolLenderActions.sol'; import { IPoolKickerActions } from './commons/IPoolKickerActions.sol'; import { IPoolTakerActions } from './commons/IPoolTakerActions.sol'; import { IPoolSettlerActions } from './commons/IPoolSettlerActions.sol'; import { IPoolImmutables } from './commons/IPoolImmutables.sol'; import { IPoolState } from './commons/IPoolState.sol'; import { IPoolDerivedState } from './commons/IPoolDerivedState.sol'; import { IPoolEvents } from './commons/IPoolEvents.sol'; import { IPoolErrors } from './commons/IPoolErrors.sol'; import { IERC3156FlashLender } from './IERC3156FlashLender.sol'; /** * @title Base Pool Interface */ interface IPool is IPoolBorrowerActions, IPoolLPActions, IPoolLenderActions, IPoolKickerActions, IPoolTakerActions, IPoolSettlerActions, IPoolImmutables, IPoolState, IPoolDerivedState, IPoolEvents, IPoolErrors, IERC3156FlashLender { } /// @dev Pool type enum - `ERC20` and `ERC721` enum PoolType { ERC20, ERC721 } /// @dev `ERC20` token interface. interface IERC20Token { function balanceOf(address account) external view returns (uint256); function burn(uint256 amount) external; function decimals() external view returns (uint8); } /// @dev `ERC721` token interface. interface IERC721Token { function transferFrom( address from, address to, uint256 tokenId ) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.15; interface IAjnaPoolUtilsInfo { function priceToIndex(uint256 price_) external pure returns (uint256); function borrowerInfo( address pool_, address borrower_ ) external view returns (uint256 debt_, uint256 collateral_, uint256 index_); function poolPricesInfo( address ajnaPool_ ) external view returns (uint256 hpb_, uint256 hpbIndex_, uint256 htp_, uint256 htpIndex_, uint256 lup_, uint256 lupIndex_); function lpToQuoteTokens( address ajnaPool_, uint256 lp_, uint256 index_ ) external view returns (uint256 quoteAmount_); function bucketInfo( address ajnaPool_, uint256 index_ ) external view returns ( uint256 price_, uint256 quoteTokens_, uint256 collateral_, uint256 bucketLP_, uint256 scale_, uint256 exchangeRate_ ); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.0; interface IAccountGuard { function owners(address) external view returns (address); function owner() external view returns (address); function setWhitelist(address target, bool status) external; function canCall( address proxy, address operator ) external view returns (bool); function permit(address caller, address target, bool allowance) external; function isWhitelisted(address target) external view returns (bool); function isWhitelistedSend(address target) external view returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.0; interface IWETH { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint) external; }
{ "metadata": { "bytecodeHash": "none" }, "optimizer": { "enabled": true, "runs": 0 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IAjnaPoolUtilsInfo","name":"_poolInfoUtils","type":"address"},{"internalType":"contract IERC20","name":"_ajnaToken","type":"address"},{"internalType":"address","name":"_WETH","type":"address"},{"internalType":"address","name":"_GUARD","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proxyAddress","type":"address"},{"indexed":false,"internalType":"string","name":"protocol","type":"string"},{"indexed":false,"internalType":"string","name":"positionType","type":"string"},{"indexed":false,"internalType":"address","name":"collateralToken","type":"address"},{"indexed":false,"internalType":"address","name":"debtToken","type":"address"}],"name":"CreatePosition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"ProxyActionsOperation","type":"event"},{"inputs":[],"name":"ARC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GUARD","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"bucket","type":"uint256"}],"name":"_validateBucketState","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ajnaToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ajnaVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"name":"convertPriceToIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"debtAmount","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bool","name":"stamploanEnabled","type":"bool"}],"name":"depositAndDraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bool","name":"stamploanEnabled","type":"bool"}],"name":"depositCollateral","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"debtAmount","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"depositCollateralAndDrawDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"debtAmount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"drawDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"getQuoteAmount","outputs":[{"internalType":"uint256","name":"quoteAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"oldPrice","type":"uint256"},{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"moveQuote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"openEarnPosition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"debtAmount","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"openPosition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"poolInfoUtils","outputs":[{"internalType":"contract IAjnaPoolUtilsInfo","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"removeCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"}],"name":"repayAndClose","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"stamploanEnabled","type":"bool"}],"name":"repayDebt","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"debtAmount","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"repayDebtAndWithdrawCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"debtAmount","type":"uint256"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"bool","name":"stamploanEnabled","type":"bool"}],"name":"repayWithdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"amountToAdd","type":"uint256"},{"internalType":"uint256","name":"oldPrice","type":"uint256"},{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"supplyAndMoveQuote","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"supplyQuote","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"amountToWithdraw","type":"uint256"},{"internalType":"uint256","name":"oldPrice","type":"uint256"},{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"withdrawAndMoveQuote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Pool","name":"pool","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"withdrawQuote","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101206040523480156200001257600080fd5b50604051620035d2380380620035d28339810160408190526200003591620001e9565b6001600160a01b038416620000915760405162461bcd60e51b815260206004820181905260248201527f6170612f706f6f6c2d696e666f2d7574696c732d7a65726f2d6164647265737360448201526064015b60405180910390fd5b6001600160a01b038316151580620000aa575046600114155b620000f85760405162461bcd60e51b815260206004820152601b60248201527f6170612f616a6e612d746f6b656e2d7a65726f2d616464726573730000000000604482015260640162000088565b6001600160a01b038216620001505760405162461bcd60e51b815260206004820152601560248201527f6170612f776574682d7a65726f2d616464726573730000000000000000000000604482015260640162000088565b6001600160a01b038116620001a85760405162461bcd60e51b815260206004820152601660248201527f6170612f67756172642d7a65726f2d6164647265737300000000000000000000604482015260640162000088565b6001600160a01b0393841660805291831660a052821660c0521660e052336101005262000251565b6001600160a01b0381168114620001e657600080fd5b50565b600080600080608085870312156200020057600080fd5b84516200020d81620001d0565b60208601519094506200022081620001d0565b60408601519093506200023381620001d0565b60608601519092506200024681620001d0565b939692955090935050565b60805160a05160c05160e051610100516132e8620002ea60003960006103c7015260006104b601526000818161034d01528181611f2f01528181611f7c015281816121be01526121f7015260006103190152600081816102b2015281816107cc0152818161095c01528181610a3c01528181610cfb01528181611447015281816115c70152818161179d0152611cab01526132e86000f3fe60806040526004361061013c5760003560e01c80630e46f6301461014157806321166476146101635780632bceabbd1461019957806332ff4c33146101ac57806334eea00a146101cc578063350c35e9146101fa578063557d06161461021a5780635a54843d1461022d5780638267d2e71461024d578063854a16941461026d578063876467f814610280578063907f2579146102a0578063a136a3a2146102d4578063a967ee2c146102f4578063ab01556114610307578063ad5c46481461033b578063ae7eabea1461036f578063bff79f821461038f578063c64609ff146103a2578063d5f39488146103b5578063d9d0373b146103e9578063de3a5a0b146103fc578063f1acf27a1461041c578063f21ead211461042f578063f5b42e961461044f578063fd52859214610462578063fe3348f9146104a4575b600080fd5b34801561014d57600080fd5b5061016161015c366004612d92565b6104d8565b005b34801561016f57600080fd5b50600054610183906001600160a01b031681565b6040516101909190612dc7565b60405180910390f35b6101616101a7366004612d92565b610652565b3480156101b857600080fd5b506101616101c7366004612ddb565b6107b2565b3480156101d857600080fd5b506101ec6101e7366004612ddb565b6108ab565b604051908152602001610190565b34801561020657600080fd5b50610161610215366004612ddb565b6109d2565b610161610228366004612d92565b610bea565b34801561023957600080fd5b50610161610248366004612d92565b610bf7565b34801561025957600080fd5b50610161610268366004612e07565b611019565b61016161027b366004612e50565b611076565b34801561028c57600080fd5b5061016161029b366004612ddb565b6110c6565b3480156102ac57600080fd5b506101837f000000000000000000000000000000000000000000000000000000000000000081565b3480156102e057600080fd5b506101616102ef366004612e07565b611105565b610161610302366004612ea6565b611376565b34801561031357600080fd5b506101837f000000000000000000000000000000000000000000000000000000000000000081565b34801561034757600080fd5b506101837f000000000000000000000000000000000000000000000000000000000000000081565b34801561037b57600080fd5b506101ec61038a366004612ec3565b611784565b61016161039d366004612e07565b611816565b6101616103b0366004612edc565b611880565b3480156103c157600080fd5b506101837f000000000000000000000000000000000000000000000000000000000000000081565b6101616103f7366004612e07565b6118cc565b34801561040857600080fd5b50610161610417366004612d92565b6119f0565b61016161042a366004612edc565b611a2d565b34801561043b57600080fd5b5061016161044a366004612d92565b611bc7565b61016161045d366004612f26565b611c0d565b34801561046e57600080fd5b5061049760405180604001604052806009815260200168416a6e615f7263313360b81b81525081565b6040516101909190612fb8565b3480156104b057600080fd5b506101837f000000000000000000000000000000000000000000000000000000000000000081565b6000836001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190612fcb565b9050600061054983611784565b9050846001600160a01b031663cfa8ff0330876001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105bd9190612fe8565b6105c79088613017565b8460006040518563ffffffff1660e01b81526004016105e9949392919061302e565b600060405180830381600087803b15801561060357600080fd5b505af1158015610617573d6000803e3d6000fd5b505050506106258285611f2d565b60405169416a6e61426f72726f7760b01b906000805160206132bc83398151915290600090a25050505050565b306001600160a01b031660008051602061329c83398151915260405180604001604052806009815260200168416a6e615f7263313360b81b815250856001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ef9190612fcb565b866001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107519190612fcb565b60405161076093929190613054565b60405180910390a2610775836101c783611784565b610780838383612025565b50506040516e416a6e61537570706c7951756f746560881b906000805160206132bc83398151915290600090a2505050565b604051630c969c4760e11b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063192d388e9061080390869086906004016130a7565b60c060405180830381865afa158015610820573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084491906130c0565b50509350505050806000148061085c5750620f424081115b6108a65760405162461bcd60e51b8152602060048201526016602482015275185c184bd89d58dad95d0b5b1c1ccb5a5b9d985b1a5960521b60448201526064015b60405180910390fd5b505050565b6000806108b783611784565b6040516353a4f8d360e11b8152600481018290523060248201529091506000906001600160a01b0386169063a749f1a6906044016040805180830381865afa158015610907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092b919061310a565b506040516343dfac7d60e01b81526001600160a01b03878116600483015260248201839052604482018590529192507f0000000000000000000000000000000000000000000000000000000000000000909116906343dfac7d90606401602060405180830381865afa1580156109a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c99190612fe8565b95945050505050565b6000826001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190612fcb565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ad685b3c856040518263ffffffff1660e01b8152600401610a869190612dc7565b60c060405180830381865afa158015610aa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac791906130c0565b95505050505050836001600160a01b031663a9ff9f77306000876001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b429190612fe8565b610b4c9088613017565b30866040518663ffffffff1660e01b8152600401610b6e95949392919061312e565b6020604051808303816000875af1158015610b8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb19190612fe8565b50610bbc8284611f2d565b6040516b416a6e61576974686472617760a01b906000805160206132bc83398151915290600090a250505050565b610775836101c783611784565b6000836001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5b9190612fcb565b90506000846001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc19190612fcb565b9050610ccd82856121bc565b610ce16001600160a01b0383168686612282565b604051632b5a16cf60e21b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ad685b3c90610d30908990600401612dc7565b60c060405180830381865afa158015610d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7191906130c0565b955050505050506000866001600160a01b031663a9ff9f7730896001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dec9190612fe8565b610df6908a613017565b8a6001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e589190612fe8565b610e62908a613017565b30876040518663ffffffff1660e01b8152600401610e8495949392919061312e565b6020604051808303816000875af1158015610ea3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec79190612fe8565b9050610ed38386611f2d565b6000876001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f379190612fe8565b610fa2838a6001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9d9190612fe8565b61234e565b610fac9190613177565b90506000610fba828961318b565b90508015610fcc57610fcc8682611f2d565b610fe16001600160a01b0387168a6000612384565b60405170416a6e615265706179576974686472617760781b906000805160206132bc83398151915290600090a2505050505050505050565b611024848484612487565b611031846101c783611784565b61103c84838361274c565b60405177416a6e615769746864726177416e644d6f766551756f746560401b906000805160206132bc83398151915290600090a250505050565b6000841180156110865750600083115b1561109c5761109785858585611105565b6110bf565b83156110ad576110978585846104d8565b82156110bf576110bf85848484611a2d565b5050505050565b6110d082826127f4565b5060405173105a9b9854995b5bdd9950dbdb1b185d195c985b60621b906000805160206132bc83398151915290600090a25050565b6000846001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa158015611145573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111699190612fcb565b90506000856001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111cf9190612fcb565b905060006111dc84611784565b90506111e882866121bc565b6111fc6001600160a01b0383168887612282565b866001600160a01b031663cfa8ff0330896001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561124a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126e9190612fe8565b611278908a613017565b848b6001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112db9190612fe8565b6112e5908b613017565b6040518563ffffffff1660e01b8152600401611304949392919061302e565b600060405180830381600087803b15801561131e57600080fd5b505af1158015611332573d6000803e3d6000fd5b505050506113408387611f2d565b60405170416a6e614465706f736974426f72726f7760781b906000805160206132bc83398151915290600090a250505050505050565b6000816001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113da9190612fcb565b90506000826001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa15801561141c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114409190612fcb565b90506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631aeaf3f886306040518363ffffffff1660e01b815260040161149392919061319e565b606060405180830381865afa1580156114b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d491906131b8565b5091509150600061151d83876001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f79573d6000803e3d6000fd5b90506000866001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561155f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115839190612fe8565b61158d9083613177565b905061159985826121bc565b6115ad6001600160a01b0386168883612282565b604051632b5a16cf60e21b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ad685b3c906115fc908b90600401612dc7565b60c060405180830381865afa158015611619573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163d91906130c0565b60405163a9ff9f7760e01b81529096506001600160a01b038e16955063a9ff9f779450611679935030925088915089908390889060040161312e565b6020604051808303816000875af1158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc9190612fe8565b506000886001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117219190612fe8565b61172b9086613177565b90506117378882611f2d565b61174c6001600160a01b0388168a6000612384565b60405170416a6e615265706179416e64436c6f736560781b906000805160206132bc83398151915290600090a2505050505050505050565b6040516326dff88560e21b8152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639b7fe21490602401602060405180830381865afa1580156117ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118109190612fe8565b92915050565b611823846101c783611784565b61182e848483612025565b505061183d846101c783611784565b61184884838361274c565b60405175416a6e61537570706c79416e644d6f766551756f746560501b906000805160206132bc83398151915290600090a250505050565b6000831180156118905750600082115b156118a5576118a0848484610bf7565b6118c6565b82156118b6576118a0848483611c0d565b81156118c6576118c684836109d2565b50505050565b306001600160a01b031660008051602061329c83398151915260405180604001604052806009815260200168416a6e615f7263313360b81b815250866001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190612fcb565b876001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119cb9190612fcb565b6040516119da939291906131e6565b60405180910390a26118c6848484846000611076565b6119fb838383612487565b60405170416a6e61576974686472617751756f746560781b906000805160206132bc83398151915290600090a2505050565b6000846001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a919190612fcb565b9050611a9d81856121bc565b6000611aa884611784565b9050611abe6001600160a01b0383168787612282565b856001600160a01b031663cfa8ff03306000848a6001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b339190612fe8565b611b3d908b613017565b6040518563ffffffff1660e01b8152600401611b5c949392919061302e565b600060405180830381600087803b158015611b7657600080fd5b505af1158015611b8a573d6000803e3d6000fd5b50505050611b9886846129a4565b6040516a105a9b9851195c1bdcda5d60aa1b906000805160206132bc83398151915290600090a2505050505050565b611bd4836101c783611784565b611bdf83838361274c565b6040516c416a6e614d6f766551756f746560981b906000805160206132bc83398151915290600090a2505050565b6000836001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c719190612fcb565b9050611c7d81846121bc565b611c916001600160a01b0382168585612282565b604051632b5a16cf60e21b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ad685b3c90611ce0908890600401612dc7565b60c060405180830381865afa158015611cfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2191906130c0565b955050505050506000856001600160a01b031663a9ff9f7730886001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9c9190612fe8565b611da69089613017565b600030876040518663ffffffff1660e01b8152600401611dca95949392919061312e565b6020604051808303816000875af1158015611de9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0d9190612fe8565b9050611e1986856129a4565b6000866001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7d9190612fe8565b611ebf83896001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f79573d6000803e3d6000fd5b611ec99190613177565b90506000611ed7828861318b565b90508015611ee957611ee98582611f2d565b611efe6001600160a01b038616896000612384565b60405168416a6e61526570617960b81b906000805160206132bc83398151915290600090a25050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03160361200d57604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b158015611fc857600080fd5b505af1158015611fdc573d6000803e3d6000fd5b505060405133925083156108fc02915083906000818181858888f193505050501580156108a6573d6000803e3d6000fd5b6120216001600160a01b0383163383612a01565b5050565b6000806000856001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa158015612068573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208c9190612fcb565b905061209881866121bc565b60006120a385611784565b90506120b96001600160a01b0383168888612282565b866001600160a01b031663f78b0cce886001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015612106573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212a9190612fe8565b6121349089613017565b8361214042600161323b565b6040516001600160e01b031960e086901b16815260048101939093526024830191909152604482015260640160408051808303816000875af115801561218a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ae919061310a565b909890975095505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03160361226d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561225057600080fd5b505af1158015612264573d6000803e3d6000fd5b50505050505050565b6120216001600160a01b038316333084612a20565b600063095ea7b360e01b838360405160240161229f9291906130a7565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915290506122dd8482612a58565b6118c6576040516001600160a01b03841660248201526000604482015261234490859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612af1565b6118c68482612af1565b600061235a828461324e565b600003612368575081611810565b816123738484612bc6565b61237d919061323b565b9392505050565b8015806123fd5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906123ba903090869060040161319e565b602060405180830381865afa1580156123d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123fb9190612fe8565b155b6124685760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161089d565b6108a68363095ea7b360e01b848460405160240161230d9291906130a7565b6000836001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124eb9190612fcb565b905060006124f883611784565b90506000600019850361257f5760405163b1f0724760e01b81526000196004820152602481018390526001600160a01b0387169063b1f072479060440160408051808303816000875af1158015612553573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612577919061310a565b509050612667565b856001600160a01b031663b1f07247876001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f09190612fe8565b6125fa9088613017565b846040518363ffffffff1660e01b8152600401612621929190918252602082015260400190565b60408051808303816000875af115801561263f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612663919061310a565b5090505b6000866001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126cb9190612fe8565b61273683896001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561270d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127319190612fe8565b612bc6565b6127409190613177565b90506122648482611f2d565b600061275783611784565b9050836001600160a01b031663332c0e436000198361277586611784565b61278042600161323b565b6040516001600160e01b031960e087901b16815260048101949094526024840192909252604483015260648201526084016060604051808303816000875af11580156127d0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226491906131b8565b600080836001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612835573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128599190612fcb565b9050600061286684611784565b604051636a9b189160e01b81526000196004820152602481018290529091506000906001600160a01b03871690636a9b18919060440160408051808303816000875af11580156128ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128de919061310a565b509050856001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561291f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129439190612fe8565b61298582886001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561270d573d6000803e3d6000fd5b61298f9190613177565b935061299b8385611f2d565b50505092915050565b801561202157816001600160a01b031663ce4396d76040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156129e557600080fd5b505af11580156129f9573d6000803e3d6000fd5b505050505050565b6108a68363a9059cbb60e01b848460405160240161230d9291906130a7565b6040516001600160a01b03808516602483015283166044820152606481018290526118c69085906323b872dd60e01b9060840161230d565b6000806000846001600160a01b031684604051612a759190613262565b6000604051808303816000865af19150503d8060008114612ab2576040519150601f19603f3d011682016040523d82523d6000602084013e612ab7565b606091505b5091509150818015612ae1575080511580612ae1575080806020019051810190612ae1919061327e565b80156109c957506109c985612bdd565b6000612b46826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612bec9092919063ffffffff16565b9050805160001480612b67575080806020019051810190612b67919061327e565b6108a65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161089d565b600081612bd38185613177565b61237d9190613017565b6001600160a01b03163b151590565b6060612bfb8484600085612c03565b949350505050565b606082471015612c645760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161089d565b600080866001600160a01b03168587604051612c809190613262565b60006040518083038185875af1925050503d8060008114612cbd576040519150601f19603f3d011682016040523d82523d6000602084013e612cc2565b606091505b5091509150612cd387838387612cde565b979650505050505050565b60608315612d4b578251600003612d4457612cf885612bdd565b612d445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161089d565b5081612bfb565b612bfb8383815115612d605781518083602001fd5b8060405162461bcd60e51b815260040161089d9190612fb8565b6001600160a01b0381168114612d8f57600080fd5b50565b600080600060608486031215612da757600080fd5b8335612db281612d7a565b95602085013595506040909401359392505050565b6001600160a01b0391909116815260200190565b60008060408385031215612dee57600080fd5b8235612df981612d7a565b946020939093013593505050565b60008060008060808587031215612e1d57600080fd5b8435612e2881612d7a565b966020860135965060408601359560600135945092505050565b8015158114612d8f57600080fd5b600080600080600060a08688031215612e6857600080fd5b8535612e7381612d7a565b94506020860135935060408601359250606086013591506080860135612e9881612e42565b809150509295509295909350565b600060208284031215612eb857600080fd5b813561237d81612d7a565b600060208284031215612ed557600080fd5b5035919050565b60008060008060808587031215612ef257600080fd5b8435612efd81612d7a565b935060208501359250604085013591506060850135612f1b81612e42565b939692955090935050565b600080600060608486031215612f3b57600080fd5b8335612f4681612d7a565b9250602084013591506040840135612f5d81612e42565b809150509250925092565b60005b83811015612f83578181015183820152602001612f6b565b50506000910152565b60008151808452612fa4816020860160208601612f68565b601f01601f19169290920160200192915050565b60208152600061237d6020830184612f8c565b600060208284031215612fdd57600080fd5b815161237d81612d7a565b600060208284031215612ffa57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761181057611810613001565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b6080815260006130676080830186612f8c565b8281036020840152600481526322b0b93760e11b60208201526040810191505060018060a01b038085166040840152808416606084015250949350505050565b6001600160a01b03929092168252602082015260400190565b60008060008060008060c087890312156130d957600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b6000806040838503121561311d57600080fd5b505080516020909101519092909150565b6001600160a01b039586168152602081019490945260408401929092529092166060820152608081019190915260a00190565b634e487b7160e01b600052601260045260246000fd5b60008261318657613186613161565b500490565b8181038181111561181057611810613001565b6001600160a01b0392831681529116602082015260400190565b6000806000606084860312156131cd57600080fd5b8351925060208401519150604084015190509250925092565b6080815260006131f96080830186612f8c565b82810360208401526006815265426f72726f7760d01b60208201526040810191505060018060a01b038085166040840152808416606084015250949350505050565b8082018082111561181057611810613001565b60008261325d5761325d613161565b500690565b60008251613274818460208701612f68565b9190910192915050565b60006020828403121561329057600080fd5b815161237d81612e4256fe76dad7077eda98c50bd77cf557ea65afdd8d9bc1f4c4ccd73fa97c3596dc5cda463f98b00a27e540083d903c04918e4d1121820e305403dd278497b3dbf172a3a164736f6c6343000812000a00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae0000000000000000000000009a96ec9b57fb64fbc60b423d1f4da7691bd35079000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000ce91349d2a4577bbd0fc91fe6019600e047f2847
Deployed Bytecode
0x60806040526004361061013c5760003560e01c80630e46f6301461014157806321166476146101635780632bceabbd1461019957806332ff4c33146101ac57806334eea00a146101cc578063350c35e9146101fa578063557d06161461021a5780635a54843d1461022d5780638267d2e71461024d578063854a16941461026d578063876467f814610280578063907f2579146102a0578063a136a3a2146102d4578063a967ee2c146102f4578063ab01556114610307578063ad5c46481461033b578063ae7eabea1461036f578063bff79f821461038f578063c64609ff146103a2578063d5f39488146103b5578063d9d0373b146103e9578063de3a5a0b146103fc578063f1acf27a1461041c578063f21ead211461042f578063f5b42e961461044f578063fd52859214610462578063fe3348f9146104a4575b600080fd5b34801561014d57600080fd5b5061016161015c366004612d92565b6104d8565b005b34801561016f57600080fd5b50600054610183906001600160a01b031681565b6040516101909190612dc7565b60405180910390f35b6101616101a7366004612d92565b610652565b3480156101b857600080fd5b506101616101c7366004612ddb565b6107b2565b3480156101d857600080fd5b506101ec6101e7366004612ddb565b6108ab565b604051908152602001610190565b34801561020657600080fd5b50610161610215366004612ddb565b6109d2565b610161610228366004612d92565b610bea565b34801561023957600080fd5b50610161610248366004612d92565b610bf7565b34801561025957600080fd5b50610161610268366004612e07565b611019565b61016161027b366004612e50565b611076565b34801561028c57600080fd5b5061016161029b366004612ddb565b6110c6565b3480156102ac57600080fd5b506101837f00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae81565b3480156102e057600080fd5b506101616102ef366004612e07565b611105565b610161610302366004612ea6565b611376565b34801561031357600080fd5b506101837f0000000000000000000000009a96ec9b57fb64fbc60b423d1f4da7691bd3507981565b34801561034757600080fd5b506101837f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b34801561037b57600080fd5b506101ec61038a366004612ec3565b611784565b61016161039d366004612e07565b611816565b6101616103b0366004612edc565b611880565b3480156103c157600080fd5b506101837f000000000000000000000000ab1a4ae0f851700cc42442c588f458b553cb262081565b6101616103f7366004612e07565b6118cc565b34801561040857600080fd5b50610161610417366004612d92565b6119f0565b61016161042a366004612edc565b611a2d565b34801561043b57600080fd5b5061016161044a366004612d92565b611bc7565b61016161045d366004612f26565b611c0d565b34801561046e57600080fd5b5061049760405180604001604052806009815260200168416a6e615f7263313360b81b81525081565b6040516101909190612fb8565b3480156104b057600080fd5b506101837f000000000000000000000000ce91349d2a4577bbd0fc91fe6019600e047f284781565b6000836001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190612fcb565b9050600061054983611784565b9050846001600160a01b031663cfa8ff0330876001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105bd9190612fe8565b6105c79088613017565b8460006040518563ffffffff1660e01b81526004016105e9949392919061302e565b600060405180830381600087803b15801561060357600080fd5b505af1158015610617573d6000803e3d6000fd5b505050506106258285611f2d565b60405169416a6e61426f72726f7760b01b906000805160206132bc83398151915290600090a25050505050565b306001600160a01b031660008051602061329c83398151915260405180604001604052806009815260200168416a6e615f7263313360b81b815250856001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ef9190612fcb565b866001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107519190612fcb565b60405161076093929190613054565b60405180910390a2610775836101c783611784565b610780838383612025565b50506040516e416a6e61537570706c7951756f746560881b906000805160206132bc83398151915290600090a2505050565b604051630c969c4760e11b81526000906001600160a01b037f00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae169063192d388e9061080390869086906004016130a7565b60c060405180830381865afa158015610820573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084491906130c0565b50509350505050806000148061085c5750620f424081115b6108a65760405162461bcd60e51b8152602060048201526016602482015275185c184bd89d58dad95d0b5b1c1ccb5a5b9d985b1a5960521b60448201526064015b60405180910390fd5b505050565b6000806108b783611784565b6040516353a4f8d360e11b8152600481018290523060248201529091506000906001600160a01b0386169063a749f1a6906044016040805180830381865afa158015610907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092b919061310a565b506040516343dfac7d60e01b81526001600160a01b03878116600483015260248201839052604482018590529192507f00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae909116906343dfac7d90606401602060405180830381865afa1580156109a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c99190612fe8565b95945050505050565b6000826001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a369190612fcb565b905060007f00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae6001600160a01b031663ad685b3c856040518263ffffffff1660e01b8152600401610a869190612dc7565b60c060405180830381865afa158015610aa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac791906130c0565b95505050505050836001600160a01b031663a9ff9f77306000876001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b429190612fe8565b610b4c9088613017565b30866040518663ffffffff1660e01b8152600401610b6e95949392919061312e565b6020604051808303816000875af1158015610b8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb19190612fe8565b50610bbc8284611f2d565b6040516b416a6e61576974686472617760a01b906000805160206132bc83398151915290600090a250505050565b610775836101c783611784565b6000836001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5b9190612fcb565b90506000846001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc19190612fcb565b9050610ccd82856121bc565b610ce16001600160a01b0383168686612282565b604051632b5a16cf60e21b81526000906001600160a01b037f00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae169063ad685b3c90610d30908990600401612dc7565b60c060405180830381865afa158015610d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7191906130c0565b955050505050506000866001600160a01b031663a9ff9f7730896001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dec9190612fe8565b610df6908a613017565b8a6001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e589190612fe8565b610e62908a613017565b30876040518663ffffffff1660e01b8152600401610e8495949392919061312e565b6020604051808303816000875af1158015610ea3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec79190612fe8565b9050610ed38386611f2d565b6000876001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f379190612fe8565b610fa2838a6001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9d9190612fe8565b61234e565b610fac9190613177565b90506000610fba828961318b565b90508015610fcc57610fcc8682611f2d565b610fe16001600160a01b0387168a6000612384565b60405170416a6e615265706179576974686472617760781b906000805160206132bc83398151915290600090a2505050505050505050565b611024848484612487565b611031846101c783611784565b61103c84838361274c565b60405177416a6e615769746864726177416e644d6f766551756f746560401b906000805160206132bc83398151915290600090a250505050565b6000841180156110865750600083115b1561109c5761109785858585611105565b6110bf565b83156110ad576110978585846104d8565b82156110bf576110bf85848484611a2d565b5050505050565b6110d082826127f4565b5060405173105a9b9854995b5bdd9950dbdb1b185d195c985b60621b906000805160206132bc83398151915290600090a25050565b6000846001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa158015611145573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111699190612fcb565b90506000856001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111cf9190612fcb565b905060006111dc84611784565b90506111e882866121bc565b6111fc6001600160a01b0383168887612282565b866001600160a01b031663cfa8ff0330896001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561124a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126e9190612fe8565b611278908a613017565b848b6001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112db9190612fe8565b6112e5908b613017565b6040518563ffffffff1660e01b8152600401611304949392919061302e565b600060405180830381600087803b15801561131e57600080fd5b505af1158015611332573d6000803e3d6000fd5b505050506113408387611f2d565b60405170416a6e614465706f736974426f72726f7760781b906000805160206132bc83398151915290600090a250505050505050565b6000816001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113da9190612fcb565b90506000826001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa15801561141c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114409190612fcb565b90506000807f00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae6001600160a01b0316631aeaf3f886306040518363ffffffff1660e01b815260040161149392919061319e565b606060405180830381865afa1580156114b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d491906131b8565b5091509150600061151d83876001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f79573d6000803e3d6000fd5b90506000866001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561155f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115839190612fe8565b61158d9083613177565b905061159985826121bc565b6115ad6001600160a01b0386168883612282565b604051632b5a16cf60e21b81526000906001600160a01b037f00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae169063ad685b3c906115fc908b90600401612dc7565b60c060405180830381865afa158015611619573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163d91906130c0565b60405163a9ff9f7760e01b81529096506001600160a01b038e16955063a9ff9f779450611679935030925088915089908390889060040161312e565b6020604051808303816000875af1158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc9190612fe8565b506000886001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117219190612fe8565b61172b9086613177565b90506117378882611f2d565b61174c6001600160a01b0388168a6000612384565b60405170416a6e615265706179416e64436c6f736560781b906000805160206132bc83398151915290600090a2505050505050505050565b6040516326dff88560e21b8152600481018290526000907f00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae6001600160a01b031690639b7fe21490602401602060405180830381865afa1580156117ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118109190612fe8565b92915050565b611823846101c783611784565b61182e848483612025565b505061183d846101c783611784565b61184884838361274c565b60405175416a6e61537570706c79416e644d6f766551756f746560501b906000805160206132bc83398151915290600090a250505050565b6000831180156118905750600082115b156118a5576118a0848484610bf7565b6118c6565b82156118b6576118a0848483611c0d565b81156118c6576118c684836109d2565b50505050565b306001600160a01b031660008051602061329c83398151915260405180604001604052806009815260200168416a6e615f7263313360b81b815250866001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190612fcb565b876001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119cb9190612fcb565b6040516119da939291906131e6565b60405180910390a26118c6848484846000611076565b6119fb838383612487565b60405170416a6e61576974686472617751756f746560781b906000805160206132bc83398151915290600090a2505050565b6000846001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a919190612fcb565b9050611a9d81856121bc565b6000611aa884611784565b9050611abe6001600160a01b0383168787612282565b856001600160a01b031663cfa8ff03306000848a6001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b339190612fe8565b611b3d908b613017565b6040518563ffffffff1660e01b8152600401611b5c949392919061302e565b600060405180830381600087803b158015611b7657600080fd5b505af1158015611b8a573d6000803e3d6000fd5b50505050611b9886846129a4565b6040516a105a9b9851195c1bdcda5d60aa1b906000805160206132bc83398151915290600090a2505050505050565b611bd4836101c783611784565b611bdf83838361274c565b6040516c416a6e614d6f766551756f746560981b906000805160206132bc83398151915290600090a2505050565b6000836001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c719190612fcb565b9050611c7d81846121bc565b611c916001600160a01b0382168585612282565b604051632b5a16cf60e21b81526000906001600160a01b037f00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae169063ad685b3c90611ce0908890600401612dc7565b60c060405180830381865afa158015611cfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2191906130c0565b955050505050506000856001600160a01b031663a9ff9f7730886001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9c9190612fe8565b611da69089613017565b600030876040518663ffffffff1660e01b8152600401611dca95949392919061312e565b6020604051808303816000875af1158015611de9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0d9190612fe8565b9050611e1986856129a4565b6000866001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7d9190612fe8565b611ebf83896001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f79573d6000803e3d6000fd5b611ec99190613177565b90506000611ed7828861318b565b90508015611ee957611ee98582611f2d565b611efe6001600160a01b038616896000612384565b60405168416a6e61526570617960b81b906000805160206132bc83398151915290600090a25050505050505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316826001600160a01b03160361200d57604051632e1a7d4d60e01b8152600481018290527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031690632e1a7d4d90602401600060405180830381600087803b158015611fc857600080fd5b505af1158015611fdc573d6000803e3d6000fd5b505060405133925083156108fc02915083906000818181858888f193505050501580156108a6573d6000803e3d6000fd5b6120216001600160a01b0383163383612a01565b5050565b6000806000856001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa158015612068573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208c9190612fcb565b905061209881866121bc565b60006120a385611784565b90506120b96001600160a01b0383168888612282565b866001600160a01b031663f78b0cce886001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa158015612106573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212a9190612fe8565b6121349089613017565b8361214042600161323b565b6040516001600160e01b031960e086901b16815260048101939093526024830191909152604482015260640160408051808303816000875af115801561218a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ae919061310a565b909890975095505050505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316826001600160a01b03160361226d577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561225057600080fd5b505af1158015612264573d6000803e3d6000fd5b50505050505050565b6120216001600160a01b038316333084612a20565b600063095ea7b360e01b838360405160240161229f9291906130a7565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915290506122dd8482612a58565b6118c6576040516001600160a01b03841660248201526000604482015261234490859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612af1565b6118c68482612af1565b600061235a828461324e565b600003612368575081611810565b816123738484612bc6565b61237d919061323b565b9392505050565b8015806123fd5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906123ba903090869060040161319e565b602060405180830381865afa1580156123d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123fb9190612fe8565b155b6124685760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161089d565b6108a68363095ea7b360e01b848460405160240161230d9291906130a7565b6000836001600160a01b031663bad346206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124eb9190612fcb565b905060006124f883611784565b90506000600019850361257f5760405163b1f0724760e01b81526000196004820152602481018390526001600160a01b0387169063b1f072479060440160408051808303816000875af1158015612553573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612577919061310a565b509050612667565b856001600160a01b031663b1f07247876001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f09190612fe8565b6125fa9088613017565b846040518363ffffffff1660e01b8152600401612621929190918252602082015260400190565b60408051808303816000875af115801561263f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612663919061310a565b5090505b6000866001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126cb9190612fe8565b61273683896001600160a01b0316637b3f86556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561270d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127319190612fe8565b612bc6565b6127409190613177565b90506122648482611f2d565b600061275783611784565b9050836001600160a01b031663332c0e436000198361277586611784565b61278042600161323b565b6040516001600160e01b031960e087901b16815260048101949094526024840192909252604483015260648201526084016060604051808303816000875af11580156127d0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226491906131b8565b600080836001600160a01b03166348d399e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612835573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128599190612fcb565b9050600061286684611784565b604051636a9b189160e01b81526000196004820152602481018290529091506000906001600160a01b03871690636a9b18919060440160408051808303816000875af11580156128ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128de919061310a565b509050856001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561291f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129439190612fe8565b61298582886001600160a01b031663ec0bdcfc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561270d573d6000803e3d6000fd5b61298f9190613177565b935061299b8385611f2d565b50505092915050565b801561202157816001600160a01b031663ce4396d76040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156129e557600080fd5b505af11580156129f9573d6000803e3d6000fd5b505050505050565b6108a68363a9059cbb60e01b848460405160240161230d9291906130a7565b6040516001600160a01b03808516602483015283166044820152606481018290526118c69085906323b872dd60e01b9060840161230d565b6000806000846001600160a01b031684604051612a759190613262565b6000604051808303816000865af19150503d8060008114612ab2576040519150601f19603f3d011682016040523d82523d6000602084013e612ab7565b606091505b5091509150818015612ae1575080511580612ae1575080806020019051810190612ae1919061327e565b80156109c957506109c985612bdd565b6000612b46826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612bec9092919063ffffffff16565b9050805160001480612b67575080806020019051810190612b67919061327e565b6108a65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161089d565b600081612bd38185613177565b61237d9190613017565b6001600160a01b03163b151590565b6060612bfb8484600085612c03565b949350505050565b606082471015612c645760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161089d565b600080866001600160a01b03168587604051612c809190613262565b60006040518083038185875af1925050503d8060008114612cbd576040519150601f19603f3d011682016040523d82523d6000602084013e612cc2565b606091505b5091509150612cd387838387612cde565b979650505050505050565b60608315612d4b578251600003612d4457612cf885612bdd565b612d445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161089d565b5081612bfb565b612bfb8383815115612d605781518083602001fd5b8060405162461bcd60e51b815260040161089d9190612fb8565b6001600160a01b0381168114612d8f57600080fd5b50565b600080600060608486031215612da757600080fd5b8335612db281612d7a565b95602085013595506040909401359392505050565b6001600160a01b0391909116815260200190565b60008060408385031215612dee57600080fd5b8235612df981612d7a565b946020939093013593505050565b60008060008060808587031215612e1d57600080fd5b8435612e2881612d7a565b966020860135965060408601359560600135945092505050565b8015158114612d8f57600080fd5b600080600080600060a08688031215612e6857600080fd5b8535612e7381612d7a565b94506020860135935060408601359250606086013591506080860135612e9881612e42565b809150509295509295909350565b600060208284031215612eb857600080fd5b813561237d81612d7a565b600060208284031215612ed557600080fd5b5035919050565b60008060008060808587031215612ef257600080fd5b8435612efd81612d7a565b935060208501359250604085013591506060850135612f1b81612e42565b939692955090935050565b600080600060608486031215612f3b57600080fd5b8335612f4681612d7a565b9250602084013591506040840135612f5d81612e42565b809150509250925092565b60005b83811015612f83578181015183820152602001612f6b565b50506000910152565b60008151808452612fa4816020860160208601612f68565b601f01601f19169290920160200192915050565b60208152600061237d6020830184612f8c565b600060208284031215612fdd57600080fd5b815161237d81612d7a565b600060208284031215612ffa57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761181057611810613001565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b6080815260006130676080830186612f8c565b8281036020840152600481526322b0b93760e11b60208201526040810191505060018060a01b038085166040840152808416606084015250949350505050565b6001600160a01b03929092168252602082015260400190565b60008060008060008060c087890312156130d957600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b6000806040838503121561311d57600080fd5b505080516020909101519092909150565b6001600160a01b039586168152602081019490945260408401929092529092166060820152608081019190915260a00190565b634e487b7160e01b600052601260045260246000fd5b60008261318657613186613161565b500490565b8181038181111561181057611810613001565b6001600160a01b0392831681529116602082015260400190565b6000806000606084860312156131cd57600080fd5b8351925060208401519150604084015190509250925092565b6080815260006131f96080830186612f8c565b82810360208401526006815265426f72726f7760d01b60208201526040810191505060018060a01b038085166040840152808416606084015250949350505050565b8082018082111561181057611810613001565b60008261325d5761325d613161565b500690565b60008251613274818460208701612f68565b9190910192915050565b60006020828403121561329057600080fd5b815161237d81612e4256fe76dad7077eda98c50bd77cf557ea65afdd8d9bc1f4c4ccd73fa97c3596dc5cda463f98b00a27e540083d903c04918e4d1121820e305403dd278497b3dbf172a3a164736f6c6343000812000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae0000000000000000000000009a96ec9b57fb64fbc60b423d1f4da7691bd35079000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000ce91349d2a4577bbd0fc91fe6019600e047f2847
-----Decoded View---------------
Arg [0] : _poolInfoUtils (address): 0x30c5eF2997d6a882DE52c4ec01B6D0a5e5B4fAAE
Arg [1] : _ajnaToken (address): 0x9a96ec9B57Fb64FbC60B423d1f4da7691Bd35079
Arg [2] : _WETH (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [3] : _GUARD (address): 0xCe91349d2A4577BBd0fC91Fe6019600e047f2847
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000030c5ef2997d6a882de52c4ec01b6d0a5e5b4faae
Arg [1] : 0000000000000000000000009a96ec9b57fb64fbc60b423d1f4da7691bd35079
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [3] : 000000000000000000000000ce91349d2a4577bbd0fc91fe6019600e047f2847
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.