More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
19437199 | 337 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ActivePool
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "./Interfaces/IActivePool.sol"; import "./Interfaces/ICollSurplusPool.sol"; import "./Dependencies/ICollateralToken.sol"; import "./Interfaces/ICdpManagerData.sol"; import "./Interfaces/IBorrowerOperations.sol"; import "./Dependencies/ERC3156FlashLender.sol"; import "./Dependencies/SafeERC20.sol"; import "./Dependencies/ReentrancyGuard.sol"; import "./Dependencies/AuthNoOwner.sol"; import "./Dependencies/BaseMath.sol"; import "./Dependencies/TwapWeightedObserver.sol"; import "./Dependencies/EbtcMath.sol"; /** * @title The Active Pool holds the collateral and EBTC debt (only accounting but not EBTC tokens) for all active cdps. * * @notice When a cdp is liquidated, it's collateral will be transferred from the Active Pool * @notice (destination may vary depending on the liquidation conditions). * @dev ActivePool also allows ERC3156 compatible flashloan of stETH token */ contract ActivePool is IActivePool, ERC3156FlashLender, ReentrancyGuard, BaseMath, AuthNoOwner, TwapWeightedObserver { using SafeERC20 for IERC20; string public constant NAME = "ActivePool"; address public immutable borrowerOperationsAddress; address public immutable cdpManagerAddress; address public immutable collSurplusPoolAddress; address public immutable feeRecipientAddress; uint256 internal systemCollShares; // deposited collateral tracker uint256 internal systemDebt; uint256 internal feeRecipientCollShares; // coll shares claimable by fee recipient ICollateralToken public immutable collateral; // --- Contract setters --- /// @notice Constructor for the ActivePool contract /// @dev Initializes the contract with the borrowerOperationsAddress, cdpManagerAddress, collateral token address, collSurplusAddress, and feeRecipientAddress /// @param _borrowerOperationsAddress The address of the Borrower Operations contract /// @param _cdpManagerAddress The address of the Cdp Manager contract /// @param _collTokenAddress The address of the collateral token /// @param _collSurplusAddress The address of the collateral surplus pool constructor( address _borrowerOperationsAddress, address _cdpManagerAddress, address _collTokenAddress, address _collSurplusAddress ) TwapWeightedObserver(0) { borrowerOperationsAddress = _borrowerOperationsAddress; cdpManagerAddress = _cdpManagerAddress; collateral = ICollateralToken(_collTokenAddress); collSurplusPoolAddress = _collSurplusAddress; feeRecipientAddress = IBorrowerOperations(borrowerOperationsAddress).feeRecipientAddress(); // TEMP: read authority to avoid signature change address _authorityAddress = address(AuthNoOwner(cdpManagerAddress).authority()); if (_authorityAddress != address(0)) { _initializeAuthority(_authorityAddress); } require(systemDebt == 0, "ActivePool: systemDebt should be 0 for TWAP initialization"); } // --- Getters for public variables. Required by IPool interface --- /// @notice Amount of stETH collateral shares in the contract /// @dev Not necessarily equal to the the contract's raw systemCollShares balance - tokens can be forcibly sent to contracts /// @return uint256 The amount of systemCollShares allocated to the pool function getSystemCollShares() external view override returns (uint256) { return systemCollShares; } /// @notice Returns the systemDebt state variable /// @dev The amount of EBTC debt in the pool. Like systemCollShares, this is not necessarily equal to the contract's EBTC token balance - tokens can be forcibly sent to contracts /// @return uint256 The amount of EBTC debt in the pool function getSystemDebt() external view override returns (uint256) { return systemDebt; } /// @notice The amount of stETH collateral shares claimable by the fee recipient /// @return uint256 The amount of collateral shares claimable by the fee recipient function getFeeRecipientClaimableCollShares() external view override returns (uint256) { return feeRecipientCollShares; } // --- Pool functionality --- /// @notice Sends stETH collateral shares to a specified account /// @dev Only for use by system contracts, the caller must be either BorrowerOperations or CdpManager /// @param _account The address of the account to send stETH to /// @param _shares The amount of stETH shares to send function transferSystemCollShares(address _account, uint256 _shares) public override { _requireCallerIsBOorCdpM(); uint256 cachedSystemCollShares = systemCollShares; require(cachedSystemCollShares >= _shares, "!ActivePoolBal"); unchecked { // Can use unchecked due to above cachedSystemCollShares -= _shares; // Updating here avoids an SLOAD } systemCollShares = cachedSystemCollShares; emit SystemCollSharesUpdated(cachedSystemCollShares); emit CollSharesTransferred(_account, _shares); _transferCollSharesWithContractHooks(_account, _shares); } /// @notice Sends stETH to a specified account, drawing from both core shares and liquidator rewards shares /// @notice Liquidator reward shares are not tracked via internal accounting in the active pool and are assumed to be present in expected amount as part of the intended behavior of BorowerOperations and CdpManager /// @dev Liquidator reward shares are added when a cdp is opened, and removed when it is closed /// @dev closeCdp() or liqudations result in the actor (borrower or liquidator respectively) receiving the liquidator reward shares /// @dev Redemptions result in the shares being sent to the coll surplus pool for claiming by the CDP owner /// @dev Note that funds in the coll surplus pool, just like liquidator reward shares, are not tracked as part of the system CR or coll of a CDP. /// @dev Requires that the caller is either BorrowerOperations or CdpManager /// @param _account The address of the account to send systemCollShares and the liquidator reward to /// @param _shares The amount of systemCollShares to send /// @param _liquidatorRewardShares The amount of the liquidator reward shares to send function transferSystemCollSharesAndLiquidatorReward( address _account, uint256 _shares, uint256 _liquidatorRewardShares ) external override { _requireCallerIsBOorCdpM(); uint256 cachedSystemCollShares = systemCollShares; require(cachedSystemCollShares >= _shares, "ActivePool: Insufficient collateral shares"); uint256 totalShares = _shares + _liquidatorRewardShares; unchecked { // Safe per the check above cachedSystemCollShares -= _shares; } systemCollShares = cachedSystemCollShares; emit SystemCollSharesUpdated(cachedSystemCollShares); emit CollSharesTransferred(_account, totalShares); _transferCollSharesWithContractHooks(_account, totalShares); } /// @notice Allocate stETH shares from the system to the fee recipient to claim at-will (pull model) /// @dev Requires that the caller is CdpManager /// @dev Only the current fee recipient address is able to claim the shares /// @dev If the fee recipient address is changed while outstanding claimable coll is available, only the new fee recipient will be able to claim the outstanding coll /// @param _shares The amount of systemCollShares to allocate to the fee recipient function allocateSystemCollSharesToFeeRecipient(uint256 _shares) external override { _requireCallerIsCdpManager(); uint256 cachedSystemCollShares = systemCollShares; require(cachedSystemCollShares >= _shares, "ActivePool: Insufficient collateral shares"); unchecked { // Safe per the check above cachedSystemCollShares -= _shares; } systemCollShares = cachedSystemCollShares; uint256 cachedFeeRecipientCollShares = feeRecipientCollShares + _shares; feeRecipientCollShares = cachedFeeRecipientCollShares; emit SystemCollSharesUpdated(cachedSystemCollShares); emit FeeRecipientClaimableCollSharesIncreased(cachedFeeRecipientCollShares, _shares); } /// @notice Helper function to transfer stETH shares to another address, ensuring to call hooks into other system pools if they are the recipient /// @param _account The address to transfer shares to /// @param _shares The amount of shares to transfer function _transferCollSharesWithContractHooks(address _account, uint256 _shares) internal { // NOTE: No need for safe transfer if the collateral asset is standard. Make sure this is the case! collateral.transferShares(_account, _shares); if (_account == collSurplusPoolAddress) { ICollSurplusPool(_account).increaseTotalSurplusCollShares(_shares); } } /// @notice Increases the tracked EBTC debt of the system by a specified amount /// @dev Managed by system contracts - requires that the caller is either BorrowerOperations or CdpManager /// @param _amount: The amount to increase the system EBTC debt by function increaseSystemDebt(uint256 _amount) external override { _requireCallerIsBOorCdpM(); uint256 cachedSystemDebt = systemDebt + _amount; uint128 castedSystemDebt = EbtcMath.toUint128(cachedSystemDebt); if (!twapDisabled) { /// @audit If TWAP fails it should allow transaction to continue. Failure is preferrable to permanent DOS and can practically be mitigated by managing the redemption baseFee. try this.setValueAndUpdate(castedSystemDebt) {} catch { twapDisabled = true; emit TwapDisabled(); } } /// @audit If above uint128 max, will have reverted in safeCast systemDebt = cachedSystemDebt; emit ActivePoolEBTCDebtUpdated(cachedSystemDebt); } /// @notice Decreases the tracked EBTC debt of the system by a specified amount /// @dev Managed by system contracts - requires that the caller is either BorrowerOperations or CdpManager /// @param _amount: The amount to decrease the system EBTC debt by function decreaseSystemDebt(uint256 _amount) external override { _requireCallerIsBOorCdpM(); uint256 cachedSystemDebt = systemDebt - _amount; uint128 castedSystemDebt = EbtcMath.toUint128(cachedSystemDebt); if (!twapDisabled) { /// @audit If TWAP fails it should allow transaction to continue. Failure is preferrable to permanent DOS and can practically be mitigated by managing the redemption baseFee. try this.setValueAndUpdate(EbtcMath.toUint128(castedSystemDebt)) {} catch { twapDisabled = true; emit TwapDisabled(); } } /// @audit If above uint128 max, will have reverted in safeCast systemDebt = cachedSystemDebt; emit ActivePoolEBTCDebtUpdated(cachedSystemDebt); } // --- 'require' functions --- /// @notice Checks if the caller is BorrowerOperations function _requireCallerIsBorrowerOperations() internal view { require( msg.sender == borrowerOperationsAddress, "ActivePool: Caller is not BorrowerOperations" ); } /// @notice Checks if the caller is either BorrowerOperations or CdpManager function _requireCallerIsBOorCdpM() internal view { require( msg.sender == borrowerOperationsAddress || msg.sender == cdpManagerAddress, "ActivePool: Caller is neither BorrowerOperations nor CdpManager" ); } /// @notice Checks if the caller is CdpManager function _requireCallerIsCdpManager() internal view { require(msg.sender == cdpManagerAddress, "ActivePool: Caller is not CdpManager"); } /// @notice Notify that stETH collateral shares have been recieved, updating internal accounting accordingly /// @param _value The amount of collateral to receive function increaseSystemCollShares(uint256 _value) external override { _requireCallerIsBorrowerOperations(); uint256 cachedSystemCollShares = systemCollShares + _value; systemCollShares = cachedSystemCollShares; emit SystemCollSharesUpdated(cachedSystemCollShares); } // === Flashloans === // /// @notice Borrow assets with a flash loan /// @dev The Collateral checks may cause reverts if you trigger a fee change big enough /// consider calling `cdpManagerAddress.syncGlobalAccountingAndGracePeriod()` /// @param receiver The address to receive the flash loan /// @param token The address of the token to loan /// @param amount The amount of tokens to loan /// @param data Additional data /// @return A boolean value indicating whether the operation was successful function flashLoan( IERC3156FlashBorrower receiver, address token, uint256 amount, bytes calldata data ) external override returns (bool) { require(amount > 0, "ActivePool: 0 Amount"); uint256 fee = flashFee(token, amount); // NOTE: Check for `token` is implicit in the requires above // also checks for paused require(amount <= maxFlashLoan(token), "ActivePool: Too much"); uint256 amountWithFee = amount + fee; uint256 oldRate = collateral.getPooledEthByShares(DECIMAL_PRECISION); collateral.transfer(address(receiver), amount); // Callback require( receiver.onFlashLoan(msg.sender, token, amount, fee, data) == FLASH_SUCCESS_VALUE, "ActivePool: IERC3156: Callback failed" ); // Transfer of (principal + Fee) from flashloan receiver collateral.transferFrom(address(receiver), address(this), amountWithFee); // Send earned fee to designated recipient collateral.transfer(feeRecipientAddress, fee); // Check new balance // NOTE: Invariant Check, technically breaks CEI but I think we must use it // NOTE: This means any balance > systemCollShares is stuck, this is also present in LUSD as is // NOTE: This check effectively prevents running 2 FL at the same time // You technically could, but you'd be having to repay any amount below systemCollShares to get Fl2 to not revert require( collateral.balanceOf(address(this)) >= collateral.getPooledEthByShares(systemCollShares), "ActivePool: Must repay Balance" ); require( collateral.sharesOf(address(this)) >= systemCollShares, "ActivePool: Must repay Share" ); require( collateral.getPooledEthByShares(DECIMAL_PRECISION) == oldRate, "ActivePool: Should keep same collateral share rate" ); emit FlashLoanSuccess(address(receiver), token, amount, fee); return true; } /// @notice Calculate the flash loan fee for a given token and amount loaned /// @param token The address of the token to calculate the fee for /// @param amount The amount of tokens to calculate the fee for /// @return The flashloan fee calcualted for given token and loan amount function flashFee(address token, uint256 amount) public view override returns (uint256) { require(token == address(collateral), "ActivePool: collateral Only"); require(!flashLoansPaused, "ActivePool: Flash Loans Paused"); return (amount * feeBps) / MAX_BPS; } /// @notice Get the maximum flash loan amount for a specific token /// @dev Exclusively used here for stETH collateral, equal to the current balance of the pool /// @param token The address of the token to get the maximum flash loan amount for /// @return The maximum available flashloan amount for the token function maxFlashLoan(address token) public view override returns (uint256) { if (token != address(collateral)) { return 0; } if (flashLoansPaused) { return 0; } return collateral.balanceOf(address(this)); } // === Governed Functions === // /// @notice Claim outstanding shares for fee recipient, updating internal accounting and transferring the shares. /// @dev Call permissinos are managed via authority for flexibility, rather than gating call to just feeRecipient. /// @dev Is likely safe as an open permission though caution should be taken. /// @param _shares The amount of shares to claim to feeRecipient function claimFeeRecipientCollShares(uint256 _shares) external override requiresAuth { ICdpManagerData(cdpManagerAddress).syncGlobalAccountingAndGracePeriod(); // Calling this increases shares so do it first uint256 cachedFeeRecipientCollShares = feeRecipientCollShares; require( cachedFeeRecipientCollShares >= _shares, "ActivePool: Insufficient fee recipient coll" ); unchecked { cachedFeeRecipientCollShares -= _shares; } feeRecipientCollShares = cachedFeeRecipientCollShares; emit FeeRecipientClaimableCollSharesDecreased(cachedFeeRecipientCollShares, _shares); collateral.transferShares(feeRecipientAddress, _shares); } /// @dev Function to move unintended dust that are not protected /// @notice moves given amount of given token (collateral is NOT allowed) /// @notice because recipient are fixed, this function is safe to be called by anyone /// @param token The token address to be swept /// @param amount The token amount to be swept function sweepToken(address token, uint256 amount) public nonReentrant requiresAuth { ICdpManagerData(cdpManagerAddress).syncGlobalAccountingAndGracePeriod(); // Accrue State First require(token != address(collateral), "ActivePool: Cannot Sweep Collateral"); uint256 balance = IERC20(token).balanceOf(address(this)); require(amount <= balance, "ActivePool: Attempt to sweep more than balance"); address cachedFeeRecipientAddress = feeRecipientAddress; // Saves an SLOAD IERC20(token).safeTransfer(cachedFeeRecipientAddress, amount); emit SweepTokenSuccess(token, amount, cachedFeeRecipientAddress); } /// @notice Sets new Fee for FlashLoans /// @param _newFee The new flashloan fee to be set function setFeeBps(uint256 _newFee) external requiresAuth { ICdpManagerData(cdpManagerAddress).syncGlobalAccountingAndGracePeriod(); // Accrue State First require(_newFee <= MAX_FEE_BPS, "ERC3156FlashLender: _newFee should <= MAX_FEE_BPS"); // set new flash fee uint256 _oldFee = feeBps; feeBps = uint16(_newFee); emit FlashFeeSet(msg.sender, _oldFee, _newFee); } /// @notice Should Flashloans be paused? /// @param _paused The flag (true or false) whether flashloan will be paused function setFlashLoansPaused(bool _paused) external requiresAuth { ICdpManagerData(cdpManagerAddress).syncGlobalAccountingAndGracePeriod(); // Accrue State First flashLoansPaused = _paused; emit FlashLoansPaused(msg.sender, _paused); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity 0.8.17; /** * @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 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-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 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); } } 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: AGPL-3.0-only pragma solidity 0.8.17; import {Authority} from "./Authority.sol"; /// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic. /// @author Modified by BadgerDAO to remove owner /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol) /// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol) contract AuthNoOwner { event AuthorityUpdated(address indexed user, Authority indexed newAuthority); Authority private _authority; bool private _authorityInitialized; modifier requiresAuth() virtual { require(isAuthorized(msg.sender, msg.sig), "Auth: UNAUTHORIZED"); _; } function authority() public view returns (Authority) { return _authority; } function authorityInitialized() public view returns (bool) { return _authorityInitialized; } function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) { Authority auth = _authority; // Memoizing authority saves us a warm SLOAD, around 100 gas. // Checking if the caller is the owner only after calling the authority saves gas in most cases, but be // aware that this makes protected functions uncallable even to the owner if the authority is out of order. return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)); } /// @notice Changed constructor to initialize to allow flexiblity of constructor vs initializer use /// @notice sets authorityInitiailzed flag to ensure only one use of function _initializeAuthority(address newAuthority) internal { require(address(_authority) == address(0), "Auth: authority is non-zero"); require(!_authorityInitialized, "Auth: authority already initialized"); _authority = Authority(newAuthority); _authorityInitialized = true; emit AuthorityUpdated(address(this), Authority(newAuthority)); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.17; /// @notice A generic interface for a contract which provides authorization data to an Auth instance. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol) /// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol) interface Authority { function canCall(address user, address target, bytes4 functionSig) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; contract BaseMath { uint256 public constant DECIMAL_PRECISION = 1e18; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; library EbtcMath { uint256 internal constant DECIMAL_PRECISION = 1e18; uint256 public constant MAX_TCR = type(uint256).max; /* Precision for Nominal ICR (independent of price). Rationale for the value: * * - Making it “too high” could lead to overflows. * - Making it “too low” could lead to an ICR equal to zero, due to truncation from Solidity floor division. * * This value of 1e20 is chosen for safety: the NICR will only overflow for numerator > ~1e39 ETH, * and will only truncate to 0 if the denominator is at least 1e20 times greater than the numerator. * */ uint256 internal constant NICR_PRECISION = 1e20; function _min(uint256 _a, uint256 _b) internal pure returns (uint256) { return (_a < _b) ? _a : _b; } function _max(uint256 _a, uint256 _b) internal pure returns (uint256) { return (_a >= _b) ? _a : _b; } /** * credit to OpenZeppelin * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "EbtcMath: downcast to uint128 will overflow"); return uint128(value); } /* * Multiply two decimal numbers and use normal rounding rules: * -round product up if 19'th mantissa digit >= 5 * -round product down if 19'th mantissa digit < 5 * * Used only inside the exponentiation, _decPow(). */ function decMul(uint256 x, uint256 y) internal pure returns (uint256 decProd) { uint256 prod_xy = x * y; decProd = (prod_xy + (DECIMAL_PRECISION / 2)) / DECIMAL_PRECISION; } /* * _decPow: Exponentiation function for 18-digit decimal base, and integer exponent n. * * Uses the efficient "exponentiation by squaring" algorithm. O(log(n)) complexity. * * Called by two functions that represent time in units of minutes: * 1) CdpManager._calcDecayedBaseRate * 2) CommunityIssuance._getCumulativeIssuanceFraction * * The exponent is capped to avoid reverting due to overflow. The cap 525600000 equals * "minutes in 1000 years": 60 * 24 * 365 * 1000 * * If a period of > 1000 years is ever used as an exponent in either of the above functions, the result will be * negligibly different from just passing the cap, since: * * In function 1), the decayed base rate will be 0 for 1000 years or > 1000 years * In function 2), the difference in tokens issued at 1000 years and any time > 1000 years, will be negligible */ function _decPow(uint256 _base, uint256 _minutes) internal pure returns (uint256) { if (_minutes > 525600000) { _minutes = 525600000; } // cap to avoid overflow if (_minutes == 0) { return DECIMAL_PRECISION; } uint256 y = DECIMAL_PRECISION; uint256 x = _base; uint256 n = _minutes; // Exponentiation-by-squaring while (n > 1) { if (n % 2 == 0) { x = decMul(x, x); n = n / 2; } else { // if (n % 2 != 0) y = decMul(x, y); x = decMul(x, x); n = (n - 1) / 2; } } return decMul(x, y); } function _getAbsoluteDifference(uint256 _a, uint256 _b) internal pure returns (uint256) { return (_a >= _b) ? (_a - _b) : (_b - _a); } function _computeNominalCR(uint256 _collShares, uint256 _debt) internal pure returns (uint256) { if (_debt > 0) { return (_collShares * NICR_PRECISION) / _debt; } // Return the maximal value for uint256 if the Cdp has a debt of 0. Represents "infinite" CR. else { // if (_debt == 0) return MAX_TCR; } } /// @dev Compute collateralization ratio, given stETH balance, price, and debt balance function _computeCR( uint256 _stEthBalance, uint256 _debt, uint256 _price ) internal pure returns (uint256) { if (_debt > 0) { uint256 newCollRatio = (_stEthBalance * _price) / _debt; return newCollRatio; } // Return the maximal value for uint256 if the Cdp has a debt of 0. Represents "infinite" CR. else { // if (_debt == 0) return MAX_TCR; } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "../Interfaces/IERC3156FlashLender.sol"; import "../Interfaces/IWETH.sol"; abstract contract ERC3156FlashLender is IERC3156FlashLender { uint256 public constant MAX_BPS = 10_000; uint256 public constant MAX_FEE_BPS = 1_000; // 10% bytes32 public constant FLASH_SUCCESS_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan"); // Functions to modify these variables must be included in impelemnting contracts if desired uint16 public feeBps = 3; // may be subject to future adjustments through protocol governance bool public flashLoansPaused; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "./IERC20.sol"; /** * Based on the stETH: * - https://docs.lido.fi/contracts/lido# */ interface ICollateralToken is IERC20 { // Returns the amount of shares that corresponds to _ethAmount protocol-controlled Ether function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256); // Returns the amount of Ether that corresponds to _sharesAmount token shares function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); // Moves `_sharesAmount` token shares from the caller's account to the `_recipient` account. function transferShares(address _recipient, uint256 _sharesAmount) external returns (uint256); // Returns the amount of shares owned by _account function sharesOf(address _account) external view returns (uint256); // Returns authorized oracle address function getOracle() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /** * Based on the stETH: * - https://docs.lido.fi/contracts/lido# */ interface ICollateralTokenOracle { // Return beacon specification data. function getBeaconSpec() external view returns ( uint64 epochsPerFrame, uint64 slotsPerEpoch, uint64 secondsPerSlot, uint64 genesisTime ); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /** * Based on the OpenZeppelin IER20 interface: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol * * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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); function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); /** * @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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /** * @dev Interface of the ERC2612 standard as defined in the EIP. * * Adds the {permit} method, which can be used to change one's * {IERC20-allowance} without having to send a transaction, by signing a * message. This allows users to spend tokens without having to hold Ether. * * See https://eips.ethereum.org/EIPS/eip-2612. * * Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/ */ interface IERC2612 { /** * @dev Sets `amount` 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: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (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 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current ERC2612 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. * * `owner` can limit the time a Permit is valid for by setting `deadline` to * a value in the near future. The deadline argument can be set to uint256(-1) to * create Permits that effectively never expire. */ function nonces(address owner) external view returns (uint256); function version() external view returns (string memory); function permitTypeHash() external view returns (bytes32); function domainSeparator() external view returns (bytes32); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.17; /// @notice Gas optimized reentrancy protection for smart contracts. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol) abstract contract ReentrancyGuard { uint256 internal constant OPEN = 1; uint256 internal constant LOCKED = 2; uint256 public locked = OPEN; modifier nonReentrant() virtual { require(locked == OPEN, "ReentrancyGuard: Reentrancy in nonReentrant call"); locked = LOCKED; _; locked = OPEN; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity 0.8.17; import "./IERC20.sol"; import "./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 Calls approve while checking bool return value, handles no-return tokens function safeApprove(IERC20 token, address spender, uint256 amount) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, amount)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /** * @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" ); } }
// SPDX-License Identifier: MIT pragma solidity 0.8.17; import {ITwapWeightedObserver} from "../Interfaces/ITwapWeightedObserver.sol"; /// @title TwapWeightedObserver /// @notice Given a value, applies a time-weighted TWAP that smooths out changes over a 7 days period /// @dev Used to get the lowest value of total supply to prevent underpaying redemptions contract TwapWeightedObserver is ITwapWeightedObserver { PackedData public data; uint128 public valueToTrack; bool public twapDisabled; constructor(uint128 initialValue) { PackedData memory cachedData = PackedData({ observerCumuVal: initialValue, accumulator: initialValue, lastObserved: uint64(block.timestamp), lastAccrued: uint64(block.timestamp), lastObservedAverage: initialValue }); valueToTrack = initialValue; data = cachedData; } /// TWAP /// event NewTrackValue(uint256 _oldValue, uint256 _newValue, uint256 _ts, uint256 _newAcc); // Set to new value, sync accumulator to now with old value // Changes in same block have no impact, as no time has expired // Effectively we use the previous block value, and we magnify it by weight function _setValue(uint128 newValue) internal { uint128 _newAcc = _updateAcc(valueToTrack); data.lastAccrued = uint64(block.timestamp); emit NewTrackValue(valueToTrack, newValue, block.timestamp, _newAcc); valueToTrack = newValue; } // Update the accumulator based on time passed function _updateAcc(uint128 oldValue) internal returns (uint128) { uint128 _newAcc = data.accumulator + oldValue * (timeToAccrue()); data.accumulator = _newAcc; return _newAcc; } /// @notice Returns the time since the last update /// @return Duration since last update /// @dev Safe from overflow for tens of thousands of years function timeToAccrue() public view returns (uint64) { return uint64(block.timestamp) - data.lastAccrued; } /// @notice Returns the accumulator value, adjusted according to the current value and block timestamp // Return the update value to now function _syncToNow() internal view returns (uint128) { return data.accumulator + (valueToTrack * (timeToAccrue())); } // == Getters == // /// @notice Returns the accumulator value, adjusted according to the current value and block timestamp function getLatestAccumulator() public view returns (uint128) { return _syncToNow(); } /// END TWAP /// /// TWAP WEIGHTED OBSERVER /// // Hardcoded TWAP Period of 7 days uint256 public constant PERIOD = 7 days; // Look at last // Linear interpolate (or prob TWAP already does that for you) /// @notice Returns the current value, adjusted according to the current value and block timestamp function observe() external returns (uint256) { // Here, we need to apply the new accumulator to skew the price in some way // The weight of the skew should be proportional to the time passed uint256 futureWeight = block.timestamp - data.lastObserved; if (futureWeight == 0) { return data.lastObservedAverage; } // A reference period is 7 days // For each second passed after update // Let's virtally sync TWAP // With a weight, that is higher, the more time has passed (uint128 virtualAvgValue, uint128 obsAcc) = _calcUpdatedAvg(); if (_checkUpdatePeriod()) { _update(virtualAvgValue, obsAcc); // May as well update // Return virtual return virtualAvgValue; } uint256 weightedAvg = uint256(data.lastObservedAverage) * (uint256(PERIOD) - uint256(futureWeight)); uint256 weightedVirtual = uint256(virtualAvgValue) * (uint256(futureWeight)); uint256 weightedMean = (weightedAvg + weightedVirtual) / PERIOD; return weightedMean; } /// @dev Usual Accumulator Math, (newAcc - acc0) / (now - t0) function _calcUpdatedAvg() internal view returns (uint128, uint128) { uint128 latestAcc = getLatestAccumulator(); uint128 avgValue = (latestAcc - data.observerCumuVal) / (uint64(block.timestamp) - data.lastObserved); return (avgValue, latestAcc); } /// @dev Utility to update internal data function _update(uint128 avgValue, uint128 obsAcc) internal { data.lastObservedAverage = avgValue; data.observerCumuVal = obsAcc; data.lastObserved = uint64(block.timestamp); } /// @dev Should we update in observe? function _checkUpdatePeriod() internal returns (bool) { return block.timestamp >= (data.lastObserved + PERIOD); } /// @dev update time-weighted Observer function update() public { if (_checkUpdatePeriod()) { (uint128 avgValue, uint128 latestAcc) = _calcUpdatedAvg(); _update(avgValue, latestAcc); } } function setValueAndUpdate(uint128 value) external { require(msg.sender == address(this), "TwapWeightedObserver: Only self call"); _setValue(value); update(); } function getData() external view returns (PackedData memory) { return data; } /// END TWAP WEIGHTED OBSERVER /// }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "./IPool.sol"; import "./ITwapWeightedObserver.sol"; interface IActivePool is IPool, ITwapWeightedObserver { // --- Events --- event ActivePoolEBTCDebtUpdated(uint256 _EBTCDebt); event SystemCollSharesUpdated(uint256 _coll); event FeeRecipientClaimableCollSharesIncreased(uint256 _coll, uint256 _fee); event FeeRecipientClaimableCollSharesDecreased(uint256 _coll, uint256 _fee); event FlashLoanSuccess( address indexed _receiver, address indexed _token, uint256 _amount, uint256 _fee ); event SweepTokenSuccess(address indexed _token, uint256 _amount, address indexed _recipient); // --- Functions --- function transferSystemCollShares(address _account, uint256 _amount) external; function increaseSystemCollShares(uint256 _value) external; function transferSystemCollSharesAndLiquidatorReward( address _account, uint256 _shares, uint256 _liquidatorRewardShares ) external; function allocateSystemCollSharesToFeeRecipient(uint256 _shares) external; function claimFeeRecipientCollShares(uint256 _shares) external; function feeRecipientAddress() external view returns (address); function getFeeRecipientClaimableCollShares() external view returns (uint256); }
// SPDX-License Identifier: MIT pragma solidity 0.8.17; interface IBaseTwapWeightedObserver { // NOTE: Packing manually is cheaper, but this is simpler to understand and follow struct PackedData { // Slot 0 // Seconds in a year: 3.154e+7 /// @dev Accumulator value recorded for TWAP Observer until last update uint128 observerCumuVal; // 3.154e+7 * 80 * 100e27 = 2.5232e+38 | log_2(100e27 * 3.154e+7 * 80) = 127.568522171 /// @dev Accumulator for TWAP globally uint128 accumulator; // 3.154e+7 * 80 * 100e27 = 2.5232e+38 | log_2(100e27 * 3.154e+7 * 80) = 127.568522171 // NOTE: We can further compress this slot but we will not be able to use only one (see u72 impl) /// So what's the point of making the code more complex? // Slot 1 /// @dev last update timestamp for TWAP Observer uint64 lastObserved; // Thousands of Years, if we use relative time we can use u32 | Relative to deploy time (as immutable) /// @dev last update timestamp for TWAP global track(spot) value uint64 lastAccrued; // Thousands of years // Expect eBTC debt to never surpass 100e27, which is 100 BILLION eBTC // log_2(100e27) = 96.3359147517 | log_2(100e27 / 1e18) = 36.5412090438 // We could use a u64 /// @dev average value since last observe uint128 lastObservedAverage; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "./IPositionManagers.sol"; // Common interface for the Cdp Manager. interface IBorrowerOperations is IPositionManagers { // --- Events --- event FeeRecipientAddressChanged(address indexed _feeRecipientAddress); event FlashLoanSuccess( address indexed _receiver, address indexed _token, uint256 _amount, uint256 _fee ); // --- Functions --- function openCdp( uint256 _EBTCAmount, bytes32 _upperHint, bytes32 _lowerHint, uint256 _stEthBalance ) external returns (bytes32); function openCdpFor( uint _EBTCAmount, bytes32 _upperHint, bytes32 _lowerHint, uint _collAmount, address _borrower ) external returns (bytes32); function addColl( bytes32 _cdpId, bytes32 _upperHint, bytes32 _lowerHint, uint256 _stEthBalanceIncrease ) external; function withdrawColl( bytes32 _cdpId, uint256 _stEthBalanceDecrease, bytes32 _upperHint, bytes32 _lowerHint ) external; function withdrawDebt( bytes32 _cdpId, uint256 _amount, bytes32 _upperHint, bytes32 _lowerHint ) external; function repayDebt( bytes32 _cdpId, uint256 _amount, bytes32 _upperHint, bytes32 _lowerHint ) external; function closeCdp(bytes32 _cdpId) external; function adjustCdp( bytes32 _cdpId, uint256 _stEthBalanceDecrease, uint256 _debtChange, bool isDebtIncrease, bytes32 _upperHint, bytes32 _lowerHint ) external; function adjustCdpWithColl( bytes32 _cdpId, uint256 _stEthBalanceDecrease, uint256 _debtChange, bool isDebtIncrease, bytes32 _upperHint, bytes32 _lowerHint, uint256 _stEthBalanceIncrease ) external; function claimSurplusCollShares() external; function feeRecipientAddress() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "./ICollSurplusPool.sol"; import "./IEBTCToken.sol"; import "./ISortedCdps.sol"; import "./IActivePool.sol"; import "./IRecoveryModeGracePeriod.sol"; import "../Dependencies/ICollateralTokenOracle.sol"; // Common interface for the Cdp Manager. interface ICdpManagerData is IRecoveryModeGracePeriod { // --- Events --- event StakingRewardSplitSet(uint256 _stakingRewardSplit); event RedemptionFeeFloorSet(uint256 _redemptionFeeFloor); event MinuteDecayFactorSet(uint256 _minuteDecayFactor); event BetaSet(uint256 _beta); event RedemptionsPaused(bool _paused); event Liquidation(uint256 _liquidatedDebt, uint256 _liquidatedColl, uint256 _liqReward); event Redemption( uint256 _debtToRedeemExpected, uint256 _debtToRedeemActual, uint256 _collSharesSent, uint256 _feeCollShares, address indexed _redeemer ); event CdpUpdated( bytes32 indexed _cdpId, address indexed _borrower, address indexed _executor, uint256 _oldDebt, uint256 _oldCollShares, uint256 _debt, uint256 _collShares, uint256 _stake, CdpOperation _operation ); event CdpLiquidated( bytes32 indexed _cdpId, address indexed _borrower, uint _debt, uint _collShares, CdpOperation _operation, address indexed _liquidator, uint _premiumToLiquidator ); event CdpPartiallyLiquidated( bytes32 indexed _cdpId, address indexed _borrower, uint256 _debt, uint256 _collShares, CdpOperation operation, address indexed _liquidator, uint _premiumToLiquidator ); event BaseRateUpdated(uint256 _baseRate); event LastRedemptionTimestampUpdated(uint256 _lastFeeOpTime); event TotalStakesUpdated(uint256 _newTotalStakes); event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot); event SystemDebtRedistributionIndexUpdated(uint256 _systemDebtRedistributionIndex); event CdpDebtRedistributionIndexUpdated(bytes32 _cdpId, uint256 _cdpDebtRedistributionIndex); event CdpArrayIndexUpdated(bytes32 _cdpId, uint256 _newIndex); event StEthIndexUpdated(uint256 _oldIndex, uint256 _newIndex, uint256 _updTimestamp); event CollateralFeePerUnitUpdated(uint256 _oldPerUnit, uint256 _newPerUnit, uint256 _feeTaken); event CdpFeeSplitApplied( bytes32 _cdpId, uint256 _oldPerUnitCdp, uint256 _newPerUnitCdp, uint256 _collReduced, uint256 _collLeft ); enum CdpOperation { openCdp, closeCdp, adjustCdp, syncAccounting, liquidateInNormalMode, liquidateInRecoveryMode, redeemCollateral, partiallyLiquidate, failedPartialRedemption } enum Status { nonExistent, active, closedByOwner, closedByLiquidation, closedByRedemption } // Store the necessary data for a cdp struct Cdp { uint256 debt; uint256 coll; uint256 stake; uint128 liquidatorRewardShares; Status status; } /* * --- Variable container structs for liquidations --- * * These structs are used to hold, return and assign variables inside the liquidation functions, * in order to avoid the error: "CompilerError: Stack too deep". **/ struct CdpDebtAndCollShares { uint256 debt; uint256 collShares; } struct LiquidationLocals { bytes32 cdpId; uint256 partialAmount; // used only for partial liquidation, default 0 means full liquidation uint256 price; uint256 ICR; bytes32 upperPartialHint; bytes32 lowerPartialHint; bool recoveryModeAtStart; uint256 TCR; uint256 totalSurplusCollShares; uint256 totalCollSharesToSend; uint256 totalDebtToBurn; uint256 totalDebtToRedistribute; uint256 totalLiquidatorRewardCollShares; } struct LiquidationRecoveryModeLocals { uint256 entireSystemDebt; uint256 entireSystemColl; uint256 totalDebtToBurn; uint256 totalCollSharesToSend; uint256 totalSurplusCollShares; bytes32 cdpId; uint256 price; uint256 ICR; uint256 totalDebtToRedistribute; uint256 totalLiquidatorRewardCollShares; } struct LocalVariables_OuterLiquidationFunction { uint256 price; bool recoveryModeAtStart; uint256 liquidatedDebt; uint256 liquidatedColl; } struct LocalVariables_LiquidationSequence { uint256 i; uint256 ICR; bytes32 cdpId; bool backToNormalMode; uint256 entireSystemDebt; uint256 entireSystemColl; uint256 price; uint256 TCR; } struct SingleRedemptionInputs { bytes32 cdpId; uint256 maxEBTCamount; uint256 price; bytes32 upperPartialRedemptionHint; bytes32 lowerPartialRedemptionHint; uint256 partialRedemptionHintNICR; } struct LiquidationValues { uint256 entireCdpDebt; uint256 debtToBurn; uint256 totalCollToSendToLiquidator; uint256 debtToRedistribute; uint256 collSurplus; uint256 liquidatorCollSharesReward; } struct LiquidationTotals { uint256 totalDebtInSequence; uint256 totalDebtToBurn; uint256 totalCollToSendToLiquidator; uint256 totalDebtToRedistribute; uint256 totalCollSurplus; uint256 totalCollReward; } // --- Variable container structs for redemptions --- struct RedemptionTotals { uint256 remainingDebtToRedeem; uint256 debtToRedeem; uint256 collSharesDrawn; uint256 totalCollSharesSurplus; uint256 feeCollShares; uint256 collSharesToRedeemer; uint256 decayedBaseRate; uint256 price; uint256 systemDebtAtStart; uint256 twapSystemDebtAtStart; uint256 systemCollSharesAtStart; uint256 tcrAtStart; } struct SingleRedemptionValues { uint256 debtToRedeem; uint256 collSharesDrawn; uint256 collSurplus; uint256 liquidatorRewardShares; bool cancelledPartial; bool fullRedemption; uint256 newPartialNICR; } function getActiveCdpsCount() external view returns (uint256); function totalStakes() external view returns (uint256); function ebtcToken() external view returns (IEBTCToken); function systemStEthFeePerUnitIndex() external view returns (uint256); function systemStEthFeePerUnitIndexError() external view returns (uint256); function stEthIndex() external view returns (uint256); function calcFeeUponStakingReward( uint256 _newIndex, uint256 _prevIndex ) external view returns (uint256, uint256, uint256); function syncGlobalAccounting() external; // Accrues StEthFeeSplit without influencing Grace Period function syncGlobalAccountingAndGracePeriod() external; // Accrues StEthFeeSplit and influences Grace Period function getAccumulatedFeeSplitApplied( bytes32 _cdpId, uint256 _systemStEthFeePerUnitIndex ) external view returns (uint256, uint256); function getCachedNominalICR(bytes32 _cdpId) external view returns (uint256); function getCachedICR(bytes32 _cdpId, uint256 _price) external view returns (uint256); function getSyncedCdpDebt(bytes32 _cdpId) external view returns (uint256); function getSyncedCdpCollShares(bytes32 _cdpId) external view returns (uint256); function getSyncedICR(bytes32 _cdpId, uint256 _price) external view returns (uint256); function getSyncedTCR(uint256 _price) external view returns (uint256); function getSyncedSystemCollShares() external view returns (uint256); function getSyncedNominalICR(bytes32 _cdpId) external view returns (uint256); function getPendingRedistributedDebt(bytes32 _cdpId) external view returns (uint256); function hasPendingRedistributedDebt(bytes32 _cdpId) external view returns (bool); function getSyncedDebtAndCollShares( bytes32 _cdpId ) external view returns (uint256 debt, uint256 collShares); function canLiquidateRecoveryMode(uint256 icr, uint256 tcr) external view returns (bool); function totalCollateralSnapshot() external view returns (uint256); function totalStakesSnapshot() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface ICollSurplusPool { // --- Events --- event SurplusCollSharesAdded( bytes32 indexed _cdpId, address indexed _account, uint256 _claimableSurplusCollShares, uint256 _surplusCollSharesAddedFromCollateral, uint256 _surplusCollSharesAddedFromLiquidatorReward ); event CollSharesTransferred(address indexed _to, uint256 _amount); event SweepTokenSuccess(address indexed _token, uint256 _amount, address indexed _recipient); // --- Contract setters --- function getTotalSurplusCollShares() external view returns (uint256); function getSurplusCollShares(address _account) external view returns (uint256); function increaseSurplusCollShares( bytes32 _cdpId, address _account, uint256 _collateralShares, uint256 _liquidatorRewardShares ) external; function claimSurplusCollShares(address _account) external; function increaseTotalSurplusCollShares(uint256 _value) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "../Dependencies/IERC20.sol"; import "../Dependencies/IERC2612.sol"; interface IEBTCToken is IERC20, IERC2612 { // --- Functions --- function mint(address _account, uint256 _amount) external; function burn(address _account, uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IERC3156FlashBorrower { /** * @dev Receive a flash loan. * @param initiator The initiator of the loan. * @param token The loan currency. * @param amount The amount of tokens lent. * @param fee The additional amount of tokens to repay. * @param data Arbitrary data structure, intended to contain user-defined parameters. * @return The keccak256 hash of "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.17; import "./IERC3156FlashBorrower.sol"; interface IERC3156FlashLender { event FlashFeeSet(address indexed _setter, uint256 _oldFee, uint256 _newFee); event MaxFlashFeeSet(address indexed _setter, uint256 _oldMaxFee, uint256 _newMaxFee); event FlashLoansPaused(address indexed _setter, bool _paused); /// @dev The amount of currency available to be lent. /// @param token The loan currency. /// @return The amount of `token` that can be borrowed. 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. /// @return The amount of `token` to be charged for the loan, 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. /// @param data Arbitrary data structure, intended to contain user-defined parameters. function flashLoan( IERC3156FlashBorrower receiver, address token, uint256 amount, bytes calldata data ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; // Common interface for the Pools. interface IPool { // --- Events --- event ETHBalanceUpdated(uint256 _newBalance); event EBTCBalanceUpdated(uint256 _newBalance); event CollSharesTransferred(address indexed _to, uint256 _amount); // --- Functions --- function getSystemCollShares() external view returns (uint256); function getSystemDebt() external view returns (uint256); function increaseSystemDebt(uint256 _amount) external; function decreaseSystemDebt(uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IPositionManagers { enum PositionManagerApproval { None, OneTime, Persistent } event PositionManagerApprovalSet( address indexed _borrower, address indexed _positionManager, PositionManagerApproval _approval ); function getPositionManagerApproval( address _borrower, address _positionManager ) external view returns (PositionManagerApproval); function setPositionManagerApproval( address _positionManager, PositionManagerApproval _approval ) external; function revokePositionManagerApproval(address _positionManager) external; function renouncePositionManagerApproval(address _borrower) external; function permitPositionManagerApproval( address _borrower, address _positionManager, PositionManagerApproval _approval, uint _deadline, uint8 v, bytes32 r, bytes32 s ) external; function version() external view returns (string memory); function permitTypeHash() external view returns (bytes32); function domainSeparator() external view returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; // Interface for State Updates that can trigger RM Liquidations interface IRecoveryModeGracePeriod { event TCRNotified(uint256 TCR); /// NOTE: Mostly for debugging to ensure synch // NOTE: Ts is implicit in events (it's added by GETH) event GracePeriodStart(); event GracePeriodEnd(); event GracePeriodDurationSet(uint256 _recoveryModeGracePeriodDuration); function notifyStartGracePeriod(uint256 tcr) external; function notifyEndGracePeriod(uint256 tcr) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; // Common interface for the SortedCdps Doubly Linked List. interface ISortedCdps { // --- Events --- event NodeAdded(bytes32 _id, uint _NICR); event NodeRemoved(bytes32 _id); // --- Functions --- function remove(bytes32 _id) external; function batchRemove(bytes32[] memory _ids) external; function reInsert(bytes32 _id, uint256 _newICR, bytes32 _prevId, bytes32 _nextId) external; function contains(bytes32 _id) external view returns (bool); function isFull() external view returns (bool); function isEmpty() external view returns (bool); function getSize() external view returns (uint256); function getMaxSize() external view returns (uint256); function getFirst() external view returns (bytes32); function getLast() external view returns (bytes32); function getNext(bytes32 _id) external view returns (bytes32); function getPrev(bytes32 _id) external view returns (bytes32); function validInsertPosition( uint256 _ICR, bytes32 _prevId, bytes32 _nextId ) external view returns (bool); function findInsertPosition( uint256 _ICR, bytes32 _prevId, bytes32 _nextId ) external view returns (bytes32, bytes32); function insert( address owner, uint256 _ICR, bytes32 _prevId, bytes32 _nextId ) external returns (bytes32); function getOwnerAddress(bytes32 _id) external pure returns (address); function nonExistId() external view returns (bytes32); function cdpCountOf(address owner) external view returns (uint256); function getCdpCountOf( address owner, bytes32 startNodeId, uint maxNodes ) external view returns (uint256, bytes32); function getCdpsOf(address owner) external view returns (bytes32[] memory); function getAllCdpsOf( address owner, bytes32 startNodeId, uint maxNodes ) external view returns (bytes32[] memory, uint256, bytes32); function cdpOfOwnerByIndex(address owner, uint256 index) external view returns (bytes32); function cdpOfOwnerByIdx( address owner, uint256 index, bytes32 startNodeId, uint maxNodes ) external view returns (bytes32, bool); function toCdpId( address owner, uint256 blockHeight, uint256 nonce ) external pure returns (bytes32); function nextCdpNonce() external view returns (uint256); }
// SPDX-License Identifier: MIT pragma solidity 0.8.17; import {IBaseTwapWeightedObserver} from "./IBaseTwapWeightedObserver.sol"; interface ITwapWeightedObserver is IBaseTwapWeightedObserver { event TwapDisabled(); function PERIOD() external view returns (uint256); function valueToTrack() external view returns (uint128); function timeToAccrue() external view returns (uint64); function getLatestAccumulator() external view returns (uint128); function observe() external returns (uint256); function update() external; function twapDisabled() external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IWETH { function deposit() external payable; function withdraw(uint256) external; function transfer(address to, uint256 amount) external returns (bool); function transferFrom(address from, address to, uint256 amount) external returns (bool); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_borrowerOperationsAddress","type":"address"},{"internalType":"address","name":"_cdpManagerAddress","type":"address"},{"internalType":"address","name":"_collTokenAddress","type":"address"},{"internalType":"address","name":"_collSurplusAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_EBTCDebt","type":"uint256"}],"name":"ActivePoolEBTCDebtUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"CollSharesTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newBalance","type":"uint256"}],"name":"EBTCBalanceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newBalance","type":"uint256"}],"name":"ETHBalanceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_coll","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"FeeRecipientClaimableCollSharesDecreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_coll","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"FeeRecipientClaimableCollSharesIncreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_setter","type":"address"},{"indexed":false,"internalType":"uint256","name":"_oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"FlashFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_receiver","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"FlashLoanSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_setter","type":"address"},{"indexed":false,"internalType":"bool","name":"_paused","type":"bool"}],"name":"FlashLoansPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_setter","type":"address"},{"indexed":false,"internalType":"uint256","name":"_oldMaxFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newMaxFee","type":"uint256"}],"name":"MaxFlashFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_ts","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newAcc","type":"uint256"}],"name":"NewTrackValue","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"_recipient","type":"address"}],"name":"SweepTokenSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_coll","type":"uint256"}],"name":"SystemCollSharesUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"TwapDisabled","type":"event"},{"inputs":[],"name":"DECIMAL_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FLASH_SUCCESS_VALUE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"allocateSystemCollSharesToFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract Authority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authorityInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"borrowerOperationsAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cdpManagerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"claimFeeRecipientCollShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collSurplusPoolAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateral","outputs":[{"internalType":"contract ICollateralToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"data","outputs":[{"internalType":"uint128","name":"observerCumuVal","type":"uint128"},{"internalType":"uint128","name":"accumulator","type":"uint128"},{"internalType":"uint64","name":"lastObserved","type":"uint64"},{"internalType":"uint64","name":"lastAccrued","type":"uint64"},{"internalType":"uint128","name":"lastObservedAverage","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"decreaseSystemDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeRecipientAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC3156FlashBorrower","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flashLoansPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getData","outputs":[{"components":[{"internalType":"uint128","name":"observerCumuVal","type":"uint128"},{"internalType":"uint128","name":"accumulator","type":"uint128"},{"internalType":"uint64","name":"lastObserved","type":"uint64"},{"internalType":"uint64","name":"lastAccrued","type":"uint64"},{"internalType":"uint128","name":"lastObservedAverage","type":"uint128"}],"internalType":"struct IBaseTwapWeightedObserver.PackedData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeRecipientClaimableCollShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLatestAccumulator","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSystemCollShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSystemDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"increaseSystemCollShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"increaseSystemDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"locked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"observe","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"setFeeBps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setFlashLoansPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"value","type":"uint128"}],"name":"setValueAndUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sweepToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timeToAccrue","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"transferSystemCollShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"uint256","name":"_liquidatorRewardShares","type":"uint256"}],"name":"transferSystemCollSharesAndLiquidatorReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"twapDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"valueToTrack","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101206040526000805461ffff19166003179055600180553480156200002457600080fd5b506040516200305a3803806200305a83398101604081905262000047916200038e565b6040805160a08082018352600080835260208084018290526001600160401b034216848601819052606085018190526080948501839052600580546001600160801b0319908116909155600393909355600480546801000000000000000083029416909117929092176001600160801b031682556001600160a01b03808a16948590528881169093528683166101005291851660c0528351633c6eacbb60e21b81529351929363f1bab2ec93818301939290918290030181865afa15801562000114573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200013a9190620003f6565b6001600160a01b031660e0816001600160a01b031681525050600060a0516001600160a01b031663bf7e214f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000196573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001bc9190620003f6565b90506001600160a01b03811615620001d957620001d98162000260565b60075415620002555760405162461bcd60e51b815260206004820152603a60248201527f416374697665506f6f6c3a2073797374656d446562742073686f756c6420626560448201527f203020666f72205457415020696e697469616c697a6174696f6e00000000000060648201526084015b60405180910390fd5b50505050506200041d565b6002546001600160a01b031615620002bb5760405162461bcd60e51b815260206004820152601b60248201527f417574683a20617574686f72697479206973206e6f6e2d7a65726f000000000060448201526064016200024c565b600254600160a01b900460ff1615620003235760405162461bcd60e51b815260206004820152602360248201527f417574683a20617574686f7269747920616c726561647920696e697469616c696044820152621e995960ea1b60648201526084016200024c565b600280546001600160a81b0319166001600160a01b038316908117600160a01b1790915560405130907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b6001600160a01b03811681146200038b57600080fd5b50565b60008060008060808587031215620003a557600080fd5b8451620003b28162000375565b6020860151909450620003c58162000375565b6040860151909350620003d88162000375565b6060860151909250620003eb8162000375565b939692955090935050565b6000602082840312156200040957600080fd5b8151620004168162000375565b9392505050565b60805160a05160c05160e05161010051612b4262000518600039600081816106a001528181610acb01528181610b5f01528181610cf101528181610da501528181610e2d01528181610eb501528181610f8e0152818161106e015281816112210152818161128e0152818161198d015281816119fe01528181611c1201526121d50152600081816106fd01528181610d760152818161195e0152611d730152600081816102ed015261224501526000818161025d015281816114110152818161163b0152818161182d01528181611b9f01528181611e080152611f9d01526000818161063001528181611f6b01526123860152612b426000f3fe608060405234801561001057600080fd5b50600436106102535760003560e01c80639f03866b11610146578063d3e0947a116100c3578063e56bb75c11610087578063e56bb75c146106dd578063e90a182f146106e5578063f1bab2ec146106f8578063f2fb47c91461071f578063facc051114610732578063fd967f471461073a57600080fd5b8063d3e0947a1461067f578063d55be8c614610692578063d8dfeb451461069b578063d9d98ce4146106c2578063e3f68388146106d557600080fd5b8063b4d1d7951161010a578063b4d1d79514610621578063b7f8cf9b1461062b578063beb8d5de14610652578063bf7e214f14610665578063cf3090121461067657600080fd5b80639f03866b1461059a578063a20baee6146105c1578063a2e62045146105d0578063a3f4df7e146105d8578063b13285ff1461060e57600080fd5b8063703dfa9a116101d45780638e0b2e0e116101985780638e0b2e0e1461052e578063970c297f1461054257806397bc1e1b146105555780639af31356146105675780639b503bae1461058757600080fd5b8063703dfa9a1461045557806370673a621461047557806372c27b621461048857806373d4a13a1461049b5780638ccfa9e61461051b57600080fd5b80633bc5de301161021b5780633bc5de301461030f57806349f047bb146103f95780635cffe9de1461040c5780635fdefb951461042f578063613255ab1461044257600080fd5b806302f6567f146102585780631424027f1461029c57806314fc78fc146102b157806324a9d853146102c75780632a9043ec146102e8575b600080fd5b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6102af6102aa36600461269e565b610743565b005b6102b96107f8565b604051908152602001610293565b6000546102d59061ffff1681565b60405161ffff9091168152602001610293565b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6103996040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526003546001600160801b038082168352600160801b91829004811660208401526004546001600160401b0380821695850195909552600160401b810490941660608401529204909116608082015290565b6040516102939190600060a0820190506001600160801b0380845116835280602085015116602084015260408401516001600160401b03808216604086015280606087015116606086015250508060808501511660808401525092915050565b6102af61040736600461269e565b6108d5565b61041f61041a3660046126cc565b6109ef565b6040519015158152602001610293565b6102af61043d36600461276a565b6111ae565b6102b9610450366004612793565b61121d565b61045d611307565b6040516001600160801b039091168152602001610293565b6102af6104833660046127b0565b611316565b6102af61049636600461269e565b6113dd565b6003546004546104dc916001600160801b0380821692600160801b928390048216926001600160401b0380831693600160401b840490911692919091041685565b604080516001600160801b03968716815294861660208601526001600160401b039384169085015291166060830152909116608082015260a001610293565b6102af6105293660046127dc565b61154e565b60055461041f90600160801b900460ff1681565b6102af61055036600461281f565b611607565b600254600160a01b900460ff1661041f565b61056f611704565b6040516001600160401b039091168152602001610293565b60005461041f9062010000900460ff1681565b6102b97f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b6102b9670de0b6b3a764000081565b6102af611724565b6106016040518060400160405280600a8152602001691058dd1a5d99541bdbdb60b21b81525081565b6040516102939190612860565b6102af61061c36600461269e565b61174f565b6102b962093a8081565b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6102af61066036600461269e565b611794565b6002546001600160a01b031661027f565b6102b960015481565b6102af61068d36600461269e565b6117f9565b6102b96103e881565b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b6102b96106d03660046127b0565b6119fa565b6006546102b9565b6008546102b9565b6102af6106f33660046127b0565b611afc565b61027f7f000000000000000000000000000000000000000000000000000000000000000081565b60055461045d906001600160801b031681565b6007546102b9565b6102b961271081565b61074b611dfd565b600654818110156107775760405162461bcd60e51b815260040161076e90612893565b60405180910390fd5b81900360068190556008546000906107909084906128f3565b6008819055604051838152909150600080516020612aed8339815191529060200160405180910390a160408051828152602081018590527f68ba5291de991d26abd65cbf507d6355ef4e4594ce2d0c65c3ea89270e41234b91015b60405180910390a1505050565b6004546000908190610813906001600160401b031642612906565b905080600003610835575050600454600160801b90046001600160801b031690565b600080610840611e81565b9150915061084c611ee1565b1561086b5761085b8282611f06565b506001600160801b031692915050565b600061087a8462093a80612906565b6004546108979190600160801b90046001600160801b0316612919565b905060006108ae856001600160801b038616612919565b9050600062093a806108c083856128f3565b6108ca9190612946565b979650505050505050565b6108dd611f60565b6000816007546108ed9190612906565b905060006108fa82612031565b600554909150600160801b900460ff166109ba5730635fdefb956109266001600160801b038416612031565b6040516001600160e01b031960e084901b1681526001600160801b0390911660048201526024015b600060405180830381600087803b15801561096857600080fd5b505af1925050508015610979575060015b6109ba576005805460ff60801b1916600160801b1790556040517fca4fc4fded1c94f9363d4949ff2be652aa20d482c12207b0e7b6290a2c03f90990600090a15b60078290556040518281527f7b49d039828591b5bc8d4f0552ab8f4d6b2499043328550c75c655d427e29613906020016107eb565b6000808411610a375760405162461bcd60e51b81526020600482015260146024820152731058dd1a5d99541bdbdb0e880c08105b5bdd5b9d60621b604482015260640161076e565b6000610a4386866119fa565b9050610a4e8661121d565b851115610a945760405162461bcd60e51b8152602060048201526014602482015273082c6e8d2eccaa0deded87440a8dede40daeac6d60631b604482015260640161076e565b6000610aa082876128f3565b604051630f451f7160e31b8152670de0b6b3a764000060048201529091506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637a28fb8890602401602060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b36919061295a565b60405163a9059cbb60e01b81526001600160a01b038b81166004830152602482018a90529192507f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af1158015610baa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bce9190612973565b506040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9906001600160a01b038b16906323e30c8b90610c279033908d908d908a908e908e90600401612990565b6020604051808303816000875af1158015610c46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6a919061295a565b14610cc55760405162461bcd60e51b815260206004820152602560248201527f416374697665506f6f6c3a2049455243333135363a2043616c6c6261636b2066604482015264185a5b195960da1b606482015260840161076e565b6040516323b872dd60e01b81526001600160a01b038a81166004830152306024830152604482018490527f000000000000000000000000000000000000000000000000000000000000000016906323b872dd906064016020604051808303816000875af1158015610d3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5e9190612973565b5060405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018590527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015610dee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e129190612973565b50600654604051630f451f7160e31b815260048101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690637a28fb8890602401602060405180830381865afa158015610e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea0919061295a565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610f04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f28919061295a565b1015610f765760405162461bcd60e51b815260206004820152601e60248201527f416374697665506f6f6c3a204d7573742072657061792042616c616e63650000604482015260640161076e565b600654604051633d7ad0b760e21b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5eb42dc90602401602060405180830381865afa158015610fdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611001919061295a565b101561104f5760405162461bcd60e51b815260206004820152601c60248201527f416374697665506f6f6c3a204d75737420726570617920536861726500000000604482015260640161076e565b604051630f451f7160e31b8152670de0b6b3a7640000600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690637a28fb8890602401602060405180830381865afa1580156110bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e1919061295a565b146111495760405162461bcd60e51b815260206004820152603260248201527f416374697665506f6f6c3a2053686f756c64206b6565702073616d6520636f6c6044820152716c61746572616c207368617265207261746560701b606482015260840161076e565b876001600160a01b0316896001600160a01b03167fbc26d11fd70e2cdca20b501a51cf33594c9f434ee2c77fe035ef21b0cf14000b8986604051611197929190918252602082015260400190565b60405180910390a350600198975050505050505050565b3330146112095760405162461bcd60e51b8152602060048201526024808201527f5477617057656967687465644f627365727665723a204f6e6c792073656c662060448201526318d85b1b60e21b606482015260840161076e565b611212816120a2565b61121a611724565b50565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461126057506000919050565b60005462010000900460ff161561127957506000919050565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156112dd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611301919061295a565b92915050565b6000611311612169565b905090565b61131e611f60565b600654818110156113625760405162461bcd60e51b815260206004820152600e60248201526d085058dd1a5d99541bdbdb10985b60921b604482015260640161076e565b8190036006819055604051818152600080516020612aed8339815191529060200160405180910390a1826001600160a01b03167f1fb7e7fce5abe8f5c5d0af41f7598d317a42cc8b71d6e75f13774066263a2814836040516113c691815260200190565b60405180910390a26113d883836121af565b505050565b6113f3336000356001600160e01b0319166122da565b61140f5760405162461bcd60e51b815260040161076e906129ec565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166307902c556040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561146a57600080fd5b505af115801561147e573d6000803e3d6000fd5b505050506103e88111156114ee5760405162461bcd60e51b815260206004820152603160248201527f45524333313536466c6173684c656e6465723a205f6e65774665652073686f756044820152706c64203c3d204d41585f4645455f42505360781b606482015260840161076e565b6000805461ffff83811661ffff1983161790925560405191169033907f36d567e1fd131473c440012eaa0903f9a646c89a1ee00ecc01c477d63d94d287906115429084908690918252602082015260400190565b60405180910390a25050565b611556611f60565b600654828110156115795760405162461bcd60e51b815260040161076e90612893565b600061158583856128f3565b91849003600681905560405181815290929150600080516020612aed8339815191529060200160405180910390a1846001600160a01b03167f1fb7e7fce5abe8f5c5d0af41f7598d317a42cc8b71d6e75f13774066263a2814826040516115ee91815260200190565b60405180910390a261160085826121af565b5050505050565b61161d336000356001600160e01b0319166122da565b6116395760405162461bcd60e51b815260040161076e906129ec565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166307902c556040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561169457600080fd5b505af11580156116a8573d6000803e3d6000fd5b505060008054841515620100000262ff000019909116179055505060405133907fa5b0db65e66479c7d3871018efb8f6b08c5bcd03b257b342d53b13c91396c3df906116f990841515815260200190565b60405180910390a250565b60045460009061131190600160401b90046001600160401b031642612a18565b61172c611ee1565b1561174d5760008061173c611e81565b9150915061174a8282611f06565b50505b565b61175761237b565b60008160065461176791906128f3565b6006819055604051818152909150600080516020612aed8339815191529060200160405180910390a15050565b61179c611f60565b6000816007546117ac91906128f3565b905060006117b982612031565b600554909150600160801b900460ff166109ba57604051635fdefb9560e01b81526001600160801b03821660048201523090635fdefb959060240161094e565b61180f336000356001600160e01b0319166122da565b61182b5760405162461bcd60e51b815260040161076e906129ec565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166307902c556040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561188657600080fd5b505af115801561189a573d6000803e3d6000fd5b5050600854915050818110156119065760405162461bcd60e51b815260206004820152602b60248201527f416374697665506f6f6c3a20496e73756666696369656e74206665652072656360448201526a1a5c1a595b9d0818dbdb1b60aa1b606482015260840161076e565b819003600881905560408051828152602081018490527f056ac240f7874fd765a8fb2abe56cda7b943cf5aa3376e5e12f39a8160aae458910160405180910390a1604051638fcb4e5b60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f00000000000000000000000000000000000000000000000000000000000000001690638fcb4e5b906044016020604051808303816000875af11580156119d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d8919061295a565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611a7d5760405162461bcd60e51b815260206004820152601b60248201527f416374697665506f6f6c3a20636f6c6c61746572616c204f6e6c790000000000604482015260640161076e565b60005462010000900460ff1615611ad65760405162461bcd60e51b815260206004820152601e60248201527f416374697665506f6f6c3a20466c617368204c6f616e73205061757365640000604482015260640161076e565b60005461271090611aeb9061ffff1684612919565b611af59190612946565b9392505050565b6001805414611b665760405162461bcd60e51b815260206004820152603060248201527f5265656e7472616e637947756172643a205265656e7472616e637920696e206e60448201526f1bdb9499595b9d1c985b9d0818d85b1b60821b606482015260840161076e565b6002600155611b81336001600160e01b0319600035166122da565b611b9d5760405162461bcd60e51b815260040161076e906129ec565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166307902c556040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611bf857600080fd5b505af1158015611c0c573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031603611c9d5760405162461bcd60e51b815260206004820152602360248201527f416374697665506f6f6c3a2043616e6e6f7420537765657020436f6c6c6174656044820152621c985b60ea1b606482015260840161076e565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d08919061295a565b905080821115611d715760405162461bcd60e51b815260206004820152602e60248201527f416374697665506f6f6c3a20417474656d707420746f207377656570206d6f7260448201526d65207468616e2062616c616e636560901b606482015260840161076e565b7f0000000000000000000000000000000000000000000000000000000000000000611da66001600160a01b0385168285612408565b806001600160a01b0316846001600160a01b03167fbd14a55ba056360d3fefd3db4cd1bef985de81f4de4ddc725962aecd0b5909e285604051611deb91815260200190565b60405180910390a35050600180555050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461174d5760405162461bcd60e51b8152602060048201526024808201527f416374697665506f6f6c3a2043616c6c6572206973206e6f74204364704d616e60448201526330b3b2b960e11b606482015260840161076e565b6000806000611e8e611307565b600454909150600090611eaa906001600160401b031642612a18565b6003546001600160401b039190911690611ecd906001600160801b031684612a3f565b611ed79190612a5f565b9491935090915050565b600454600090611efe9062093a80906001600160401b03166128f3565b421015905090565b60048054600380546001600160801b0319166001600160801b039485161790556fffffffffffffffff000000000000000016600160801b939092169290920267ffffffffffffffff191617426001600160401b0316179055565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480611fbf5750336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016145b61174d5760405162461bcd60e51b815260206004820152603f60248201527f416374697665506f6f6c3a2043616c6c6572206973206e65697468657220426f60448201527f72726f7765724f7065726174696f6e73206e6f72204364704d616e6167657200606482015260840161076e565b60006001600160801b0382111561209e5760405162461bcd60e51b815260206004820152602b60248201527f456274634d6174683a20646f776e6361737420746f2075696e7431323820776960448201526a6c6c206f766572666c6f7760a81b606482015260840161076e565b5090565b6005546000906120ba906001600160801b031661245a565b600480546fffffffffffffffff00000000000000001916600160401b426001600160401b0381169190910291909117909155600554604080516001600160801b039283168152868316602082015290810192909252821660608201529091507fd8e8737aab1e0322d94269935b3e71b256749666a1a909818cd79a6766b217379060800160405180910390a150600580546001600160801b0319166001600160801b0392909216919091179055565b6000612173611704565b600554612192916001600160401b0316906001600160801b0316612a85565b6003546113119190600160801b90046001600160801b0316612ab0565b604051638fcb4e5b60e01b81526001600160a01b038381166004830152602482018390527f00000000000000000000000000000000000000000000000000000000000000001690638fcb4e5b906044016020604051808303816000875af115801561221e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612242919061295a565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03160361174a5760405163855ff31760e01b8152600481018290526001600160a01b0383169063855ff31790602401600060405180830381600087803b1580156122be57600080fd5b505af11580156122d2573d6000803e3d6000fd5b505050505050565b6002546000906001600160a01b03168015801590612373575060405163b700961360e01b81526001600160a01b0385811660048301523060248301526001600160e01b03198516604483015282169063b700961390606401602060405180830381865afa15801561234f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123739190612973565b949350505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461174d5760405162461bcd60e51b815260206004820152602c60248201527f416374697665506f6f6c3a2043616c6c6572206973206e6f7420426f72726f7760448201526b65724f7065726174696f6e7360a01b606482015260840161076e565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113d89084906124b6565b600080612465611704565b612478906001600160401b031684612a85565b6003546124959190600160801b90046001600160801b0316612ab0565b600380546001600160801b03808416600160801b0291161790559392505050565b600061250b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661258b9092919063ffffffff16565b905080516000148061252c57508080602001905181019061252c9190612973565b6113d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161076e565b6060612373848460008585600080866001600160a01b031685876040516125b29190612ad0565b60006040518083038185875af1925050503d80600081146125ef576040519150601f19603f3d011682016040523d82523d6000602084013e6125f4565b606091505b50915091506108ca878383876060831561266f578251600003612668576001600160a01b0385163b6126685760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161076e565b5081612373565b61237383838151156126845781518083602001fd5b8060405162461bcd60e51b815260040161076e9190612860565b6000602082840312156126b057600080fd5b5035919050565b6001600160a01b038116811461121a57600080fd5b6000806000806000608086880312156126e457600080fd5b85356126ef816126b7565b945060208601356126ff816126b7565b93506040860135925060608601356001600160401b038082111561272257600080fd5b818801915088601f83011261273657600080fd5b81358181111561274557600080fd5b89602082850101111561275757600080fd5b9699959850939650602001949392505050565b60006020828403121561277c57600080fd5b81356001600160801b0381168114611af557600080fd5b6000602082840312156127a557600080fd5b8135611af5816126b7565b600080604083850312156127c357600080fd5b82356127ce816126b7565b946020939093013593505050565b6000806000606084860312156127f157600080fd5b83356127fc816126b7565b95602085013595506040909401359392505050565b801515811461121a57600080fd5b60006020828403121561283157600080fd5b8135611af581612811565b60005b8381101561285757818101518382015260200161283f565b50506000910152565b602081526000825180602084015261287f81604085016020870161283c565b601f01601f19169190910160400192915050565b6020808252602a908201527f416374697665506f6f6c3a20496e73756666696369656e7420636f6c6c61746560408201526972616c2073686172657360b01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820180821115611301576113016128dd565b81810381811115611301576113016128dd565b8082028115828204841417611301576113016128dd565b634e487b7160e01b600052601260045260246000fd5b60008261295557612955612930565b500490565b60006020828403121561296c57600080fd5b5051919050565b60006020828403121561298557600080fd5b8151611af581612811565b6001600160a01b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c0840137600060c0848401015260c0601f19601f8501168301019050979650505050505050565b602080825260129082015271105d5d1a0e8815539055551213d49256915160721b604082015260600190565b6001600160401b03828116828216039080821115612a3857612a386128dd565b5092915050565b6001600160801b03828116828216039080821115612a3857612a386128dd565b60006001600160801b0380841680612a7957612a79612930565b92169190910492915050565b6001600160801b03818116838216028082169190828114612aa857612aa86128dd565b505092915050565b6001600160801b03818116838216019080821115612a3857612a386128dd565b60008251612ae281846020870161283c565b919091019291505056fed16483466b463d83139bd6faa077189744e8d5b1ba48b88c0f6d06eda7660ca8a2646970667358221220c5698df8530361251acb57ac533336505e88f1fceebc66dfb14a041a7bd091bd64736f6c63430008110033000000000000000000000000d366e016ae0677cdce93472e603b75051e022ad0000000000000000000000000c4cbae499bb4ca41e78f52f07f5d98c375711774000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000335982dae827049d35f09d5ec927de2bc38df3de
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102535760003560e01c80639f03866b11610146578063d3e0947a116100c3578063e56bb75c11610087578063e56bb75c146106dd578063e90a182f146106e5578063f1bab2ec146106f8578063f2fb47c91461071f578063facc051114610732578063fd967f471461073a57600080fd5b8063d3e0947a1461067f578063d55be8c614610692578063d8dfeb451461069b578063d9d98ce4146106c2578063e3f68388146106d557600080fd5b8063b4d1d7951161010a578063b4d1d79514610621578063b7f8cf9b1461062b578063beb8d5de14610652578063bf7e214f14610665578063cf3090121461067657600080fd5b80639f03866b1461059a578063a20baee6146105c1578063a2e62045146105d0578063a3f4df7e146105d8578063b13285ff1461060e57600080fd5b8063703dfa9a116101d45780638e0b2e0e116101985780638e0b2e0e1461052e578063970c297f1461054257806397bc1e1b146105555780639af31356146105675780639b503bae1461058757600080fd5b8063703dfa9a1461045557806370673a621461047557806372c27b621461048857806373d4a13a1461049b5780638ccfa9e61461051b57600080fd5b80633bc5de301161021b5780633bc5de301461030f57806349f047bb146103f95780635cffe9de1461040c5780635fdefb951461042f578063613255ab1461044257600080fd5b806302f6567f146102585780631424027f1461029c57806314fc78fc146102b157806324a9d853146102c75780632a9043ec146102e8575b600080fd5b61027f7f000000000000000000000000c4cbae499bb4ca41e78f52f07f5d98c37571177481565b6040516001600160a01b0390911681526020015b60405180910390f35b6102af6102aa36600461269e565b610743565b005b6102b96107f8565b604051908152602001610293565b6000546102d59061ffff1681565b60405161ffff9091168152602001610293565b61027f7f000000000000000000000000335982dae827049d35f09d5ec927de2bc38df3de81565b6103996040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526003546001600160801b038082168352600160801b91829004811660208401526004546001600160401b0380821695850195909552600160401b810490941660608401529204909116608082015290565b6040516102939190600060a0820190506001600160801b0380845116835280602085015116602084015260408401516001600160401b03808216604086015280606087015116606086015250508060808501511660808401525092915050565b6102af61040736600461269e565b6108d5565b61041f61041a3660046126cc565b6109ef565b6040519015158152602001610293565b6102af61043d36600461276a565b6111ae565b6102b9610450366004612793565b61121d565b61045d611307565b6040516001600160801b039091168152602001610293565b6102af6104833660046127b0565b611316565b6102af61049636600461269e565b6113dd565b6003546004546104dc916001600160801b0380821692600160801b928390048216926001600160401b0380831693600160401b840490911692919091041685565b604080516001600160801b03968716815294861660208601526001600160401b039384169085015291166060830152909116608082015260a001610293565b6102af6105293660046127dc565b61154e565b60055461041f90600160801b900460ff1681565b6102af61055036600461281f565b611607565b600254600160a01b900460ff1661041f565b61056f611704565b6040516001600160401b039091168152602001610293565b60005461041f9062010000900460ff1681565b6102b97f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b6102b9670de0b6b3a764000081565b6102af611724565b6106016040518060400160405280600a8152602001691058dd1a5d99541bdbdb60b21b81525081565b6040516102939190612860565b6102af61061c36600461269e565b61174f565b6102b962093a8081565b61027f7f000000000000000000000000d366e016ae0677cdce93472e603b75051e022ad081565b6102af61066036600461269e565b611794565b6002546001600160a01b031661027f565b6102b960015481565b6102af61068d36600461269e565b6117f9565b6102b96103e881565b61027f7f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe8481565b6102b96106d03660046127b0565b6119fa565b6006546102b9565b6008546102b9565b6102af6106f33660046127b0565b611afc565b61027f7f0000000000000000000000002ceb95d4a67bf771f1165659df3d11d8871e906f81565b60055461045d906001600160801b031681565b6007546102b9565b6102b961271081565b61074b611dfd565b600654818110156107775760405162461bcd60e51b815260040161076e90612893565b60405180910390fd5b81900360068190556008546000906107909084906128f3565b6008819055604051838152909150600080516020612aed8339815191529060200160405180910390a160408051828152602081018590527f68ba5291de991d26abd65cbf507d6355ef4e4594ce2d0c65c3ea89270e41234b91015b60405180910390a1505050565b6004546000908190610813906001600160401b031642612906565b905080600003610835575050600454600160801b90046001600160801b031690565b600080610840611e81565b9150915061084c611ee1565b1561086b5761085b8282611f06565b506001600160801b031692915050565b600061087a8462093a80612906565b6004546108979190600160801b90046001600160801b0316612919565b905060006108ae856001600160801b038616612919565b9050600062093a806108c083856128f3565b6108ca9190612946565b979650505050505050565b6108dd611f60565b6000816007546108ed9190612906565b905060006108fa82612031565b600554909150600160801b900460ff166109ba5730635fdefb956109266001600160801b038416612031565b6040516001600160e01b031960e084901b1681526001600160801b0390911660048201526024015b600060405180830381600087803b15801561096857600080fd5b505af1925050508015610979575060015b6109ba576005805460ff60801b1916600160801b1790556040517fca4fc4fded1c94f9363d4949ff2be652aa20d482c12207b0e7b6290a2c03f90990600090a15b60078290556040518281527f7b49d039828591b5bc8d4f0552ab8f4d6b2499043328550c75c655d427e29613906020016107eb565b6000808411610a375760405162461bcd60e51b81526020600482015260146024820152731058dd1a5d99541bdbdb0e880c08105b5bdd5b9d60621b604482015260640161076e565b6000610a4386866119fa565b9050610a4e8661121d565b851115610a945760405162461bcd60e51b8152602060048201526014602482015273082c6e8d2eccaa0deded87440a8dede40daeac6d60631b604482015260640161076e565b6000610aa082876128f3565b604051630f451f7160e31b8152670de0b6b3a764000060048201529091506000906001600160a01b037f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe841690637a28fb8890602401602060405180830381865afa158015610b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b36919061295a565b60405163a9059cbb60e01b81526001600160a01b038b81166004830152602482018a90529192507f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe849091169063a9059cbb906044016020604051808303816000875af1158015610baa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bce9190612973565b506040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9906001600160a01b038b16906323e30c8b90610c279033908d908d908a908e908e90600401612990565b6020604051808303816000875af1158015610c46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6a919061295a565b14610cc55760405162461bcd60e51b815260206004820152602560248201527f416374697665506f6f6c3a2049455243333135363a2043616c6c6261636b2066604482015264185a5b195960da1b606482015260840161076e565b6040516323b872dd60e01b81526001600160a01b038a81166004830152306024830152604482018490527f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe8416906323b872dd906064016020604051808303816000875af1158015610d3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5e9190612973565b5060405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000002ceb95d4a67bf771f1165659df3d11d8871e906f81166004830152602482018590527f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84169063a9059cbb906044016020604051808303816000875af1158015610dee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e129190612973565b50600654604051630f451f7160e31b815260048101919091527f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b031690637a28fb8890602401602060405180830381865afa158015610e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea0919061295a565b6040516370a0823160e01b81523060048201527f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b0316906370a0823190602401602060405180830381865afa158015610f04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f28919061295a565b1015610f765760405162461bcd60e51b815260206004820152601e60248201527f416374697665506f6f6c3a204d7573742072657061792042616c616e63650000604482015260640161076e565b600654604051633d7ad0b760e21b81523060048201527f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b03169063f5eb42dc90602401602060405180830381865afa158015610fdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611001919061295a565b101561104f5760405162461bcd60e51b815260206004820152601c60248201527f416374697665506f6f6c3a204d75737420726570617920536861726500000000604482015260640161076e565b604051630f451f7160e31b8152670de0b6b3a7640000600482015281907f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b031690637a28fb8890602401602060405180830381865afa1580156110bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e1919061295a565b146111495760405162461bcd60e51b815260206004820152603260248201527f416374697665506f6f6c3a2053686f756c64206b6565702073616d6520636f6c6044820152716c61746572616c207368617265207261746560701b606482015260840161076e565b876001600160a01b0316896001600160a01b03167fbc26d11fd70e2cdca20b501a51cf33594c9f434ee2c77fe035ef21b0cf14000b8986604051611197929190918252602082015260400190565b60405180910390a350600198975050505050505050565b3330146112095760405162461bcd60e51b8152602060048201526024808201527f5477617057656967687465644f627365727665723a204f6e6c792073656c662060448201526318d85b1b60e21b606482015260840161076e565b611212816120a2565b61121a611724565b50565b60007f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b0316826001600160a01b03161461126057506000919050565b60005462010000900460ff161561127957506000919050565b6040516370a0823160e01b81523060048201527f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b0316906370a0823190602401602060405180830381865afa1580156112dd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611301919061295a565b92915050565b6000611311612169565b905090565b61131e611f60565b600654818110156113625760405162461bcd60e51b815260206004820152600e60248201526d085058dd1a5d99541bdbdb10985b60921b604482015260640161076e565b8190036006819055604051818152600080516020612aed8339815191529060200160405180910390a1826001600160a01b03167f1fb7e7fce5abe8f5c5d0af41f7598d317a42cc8b71d6e75f13774066263a2814836040516113c691815260200190565b60405180910390a26113d883836121af565b505050565b6113f3336000356001600160e01b0319166122da565b61140f5760405162461bcd60e51b815260040161076e906129ec565b7f000000000000000000000000c4cbae499bb4ca41e78f52f07f5d98c3757117746001600160a01b03166307902c556040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561146a57600080fd5b505af115801561147e573d6000803e3d6000fd5b505050506103e88111156114ee5760405162461bcd60e51b815260206004820152603160248201527f45524333313536466c6173684c656e6465723a205f6e65774665652073686f756044820152706c64203c3d204d41585f4645455f42505360781b606482015260840161076e565b6000805461ffff83811661ffff1983161790925560405191169033907f36d567e1fd131473c440012eaa0903f9a646c89a1ee00ecc01c477d63d94d287906115429084908690918252602082015260400190565b60405180910390a25050565b611556611f60565b600654828110156115795760405162461bcd60e51b815260040161076e90612893565b600061158583856128f3565b91849003600681905560405181815290929150600080516020612aed8339815191529060200160405180910390a1846001600160a01b03167f1fb7e7fce5abe8f5c5d0af41f7598d317a42cc8b71d6e75f13774066263a2814826040516115ee91815260200190565b60405180910390a261160085826121af565b5050505050565b61161d336000356001600160e01b0319166122da565b6116395760405162461bcd60e51b815260040161076e906129ec565b7f000000000000000000000000c4cbae499bb4ca41e78f52f07f5d98c3757117746001600160a01b03166307902c556040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561169457600080fd5b505af11580156116a8573d6000803e3d6000fd5b505060008054841515620100000262ff000019909116179055505060405133907fa5b0db65e66479c7d3871018efb8f6b08c5bcd03b257b342d53b13c91396c3df906116f990841515815260200190565b60405180910390a250565b60045460009061131190600160401b90046001600160401b031642612a18565b61172c611ee1565b1561174d5760008061173c611e81565b9150915061174a8282611f06565b50505b565b61175761237b565b60008160065461176791906128f3565b6006819055604051818152909150600080516020612aed8339815191529060200160405180910390a15050565b61179c611f60565b6000816007546117ac91906128f3565b905060006117b982612031565b600554909150600160801b900460ff166109ba57604051635fdefb9560e01b81526001600160801b03821660048201523090635fdefb959060240161094e565b61180f336000356001600160e01b0319166122da565b61182b5760405162461bcd60e51b815260040161076e906129ec565b7f000000000000000000000000c4cbae499bb4ca41e78f52f07f5d98c3757117746001600160a01b03166307902c556040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561188657600080fd5b505af115801561189a573d6000803e3d6000fd5b5050600854915050818110156119065760405162461bcd60e51b815260206004820152602b60248201527f416374697665506f6f6c3a20496e73756666696369656e74206665652072656360448201526a1a5c1a595b9d0818dbdb1b60aa1b606482015260840161076e565b819003600881905560408051828152602081018490527f056ac240f7874fd765a8fb2abe56cda7b943cf5aa3376e5e12f39a8160aae458910160405180910390a1604051638fcb4e5b60e01b81526001600160a01b037f0000000000000000000000002ceb95d4a67bf771f1165659df3d11d8871e906f81166004830152602482018490527f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe841690638fcb4e5b906044016020604051808303816000875af11580156119d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d8919061295a565b60007f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b0316836001600160a01b031614611a7d5760405162461bcd60e51b815260206004820152601b60248201527f416374697665506f6f6c3a20636f6c6c61746572616c204f6e6c790000000000604482015260640161076e565b60005462010000900460ff1615611ad65760405162461bcd60e51b815260206004820152601e60248201527f416374697665506f6f6c3a20466c617368204c6f616e73205061757365640000604482015260640161076e565b60005461271090611aeb9061ffff1684612919565b611af59190612946565b9392505050565b6001805414611b665760405162461bcd60e51b815260206004820152603060248201527f5265656e7472616e637947756172643a205265656e7472616e637920696e206e60448201526f1bdb9499595b9d1c985b9d0818d85b1b60821b606482015260840161076e565b6002600155611b81336001600160e01b0319600035166122da565b611b9d5760405162461bcd60e51b815260040161076e906129ec565b7f000000000000000000000000c4cbae499bb4ca41e78f52f07f5d98c3757117746001600160a01b03166307902c556040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611bf857600080fd5b505af1158015611c0c573d6000803e3d6000fd5b505050507f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b0316826001600160a01b031603611c9d5760405162461bcd60e51b815260206004820152602360248201527f416374697665506f6f6c3a2043616e6e6f7420537765657020436f6c6c6174656044820152621c985b60ea1b606482015260840161076e565b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015611ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d08919061295a565b905080821115611d715760405162461bcd60e51b815260206004820152602e60248201527f416374697665506f6f6c3a20417474656d707420746f207377656570206d6f7260448201526d65207468616e2062616c616e636560901b606482015260840161076e565b7f0000000000000000000000002ceb95d4a67bf771f1165659df3d11d8871e906f611da66001600160a01b0385168285612408565b806001600160a01b0316846001600160a01b03167fbd14a55ba056360d3fefd3db4cd1bef985de81f4de4ddc725962aecd0b5909e285604051611deb91815260200190565b60405180910390a35050600180555050565b336001600160a01b037f000000000000000000000000c4cbae499bb4ca41e78f52f07f5d98c375711774161461174d5760405162461bcd60e51b8152602060048201526024808201527f416374697665506f6f6c3a2043616c6c6572206973206e6f74204364704d616e60448201526330b3b2b960e11b606482015260840161076e565b6000806000611e8e611307565b600454909150600090611eaa906001600160401b031642612a18565b6003546001600160401b039190911690611ecd906001600160801b031684612a3f565b611ed79190612a5f565b9491935090915050565b600454600090611efe9062093a80906001600160401b03166128f3565b421015905090565b60048054600380546001600160801b0319166001600160801b039485161790556fffffffffffffffff000000000000000016600160801b939092169290920267ffffffffffffffff191617426001600160401b0316179055565b336001600160a01b037f000000000000000000000000d366e016ae0677cdce93472e603b75051e022ad0161480611fbf5750336001600160a01b037f000000000000000000000000c4cbae499bb4ca41e78f52f07f5d98c37571177416145b61174d5760405162461bcd60e51b815260206004820152603f60248201527f416374697665506f6f6c3a2043616c6c6572206973206e65697468657220426f60448201527f72726f7765724f7065726174696f6e73206e6f72204364704d616e6167657200606482015260840161076e565b60006001600160801b0382111561209e5760405162461bcd60e51b815260206004820152602b60248201527f456274634d6174683a20646f776e6361737420746f2075696e7431323820776960448201526a6c6c206f766572666c6f7760a81b606482015260840161076e565b5090565b6005546000906120ba906001600160801b031661245a565b600480546fffffffffffffffff00000000000000001916600160401b426001600160401b0381169190910291909117909155600554604080516001600160801b039283168152868316602082015290810192909252821660608201529091507fd8e8737aab1e0322d94269935b3e71b256749666a1a909818cd79a6766b217379060800160405180910390a150600580546001600160801b0319166001600160801b0392909216919091179055565b6000612173611704565b600554612192916001600160401b0316906001600160801b0316612a85565b6003546113119190600160801b90046001600160801b0316612ab0565b604051638fcb4e5b60e01b81526001600160a01b038381166004830152602482018390527f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe841690638fcb4e5b906044016020604051808303816000875af115801561221e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612242919061295a565b507f000000000000000000000000335982dae827049d35f09d5ec927de2bc38df3de6001600160a01b0316826001600160a01b03160361174a5760405163855ff31760e01b8152600481018290526001600160a01b0383169063855ff31790602401600060405180830381600087803b1580156122be57600080fd5b505af11580156122d2573d6000803e3d6000fd5b505050505050565b6002546000906001600160a01b03168015801590612373575060405163b700961360e01b81526001600160a01b0385811660048301523060248301526001600160e01b03198516604483015282169063b700961390606401602060405180830381865afa15801561234f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123739190612973565b949350505050565b336001600160a01b037f000000000000000000000000d366e016ae0677cdce93472e603b75051e022ad0161461174d5760405162461bcd60e51b815260206004820152602c60248201527f416374697665506f6f6c3a2043616c6c6572206973206e6f7420426f72726f7760448201526b65724f7065726174696f6e7360a01b606482015260840161076e565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526113d89084906124b6565b600080612465611704565b612478906001600160401b031684612a85565b6003546124959190600160801b90046001600160801b0316612ab0565b600380546001600160801b03808416600160801b0291161790559392505050565b600061250b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661258b9092919063ffffffff16565b905080516000148061252c57508080602001905181019061252c9190612973565b6113d85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161076e565b6060612373848460008585600080866001600160a01b031685876040516125b29190612ad0565b60006040518083038185875af1925050503d80600081146125ef576040519150601f19603f3d011682016040523d82523d6000602084013e6125f4565b606091505b50915091506108ca878383876060831561266f578251600003612668576001600160a01b0385163b6126685760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161076e565b5081612373565b61237383838151156126845781518083602001fd5b8060405162461bcd60e51b815260040161076e9190612860565b6000602082840312156126b057600080fd5b5035919050565b6001600160a01b038116811461121a57600080fd5b6000806000806000608086880312156126e457600080fd5b85356126ef816126b7565b945060208601356126ff816126b7565b93506040860135925060608601356001600160401b038082111561272257600080fd5b818801915088601f83011261273657600080fd5b81358181111561274557600080fd5b89602082850101111561275757600080fd5b9699959850939650602001949392505050565b60006020828403121561277c57600080fd5b81356001600160801b0381168114611af557600080fd5b6000602082840312156127a557600080fd5b8135611af5816126b7565b600080604083850312156127c357600080fd5b82356127ce816126b7565b946020939093013593505050565b6000806000606084860312156127f157600080fd5b83356127fc816126b7565b95602085013595506040909401359392505050565b801515811461121a57600080fd5b60006020828403121561283157600080fd5b8135611af581612811565b60005b8381101561285757818101518382015260200161283f565b50506000910152565b602081526000825180602084015261287f81604085016020870161283c565b601f01601f19169190910160400192915050565b6020808252602a908201527f416374697665506f6f6c3a20496e73756666696369656e7420636f6c6c61746560408201526972616c2073686172657360b01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b80820180821115611301576113016128dd565b81810381811115611301576113016128dd565b8082028115828204841417611301576113016128dd565b634e487b7160e01b600052601260045260246000fd5b60008261295557612955612930565b500490565b60006020828403121561296c57600080fd5b5051919050565b60006020828403121561298557600080fd5b8151611af581612811565b6001600160a01b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c0840137600060c0848401015260c0601f19601f8501168301019050979650505050505050565b602080825260129082015271105d5d1a0e8815539055551213d49256915160721b604082015260600190565b6001600160401b03828116828216039080821115612a3857612a386128dd565b5092915050565b6001600160801b03828116828216039080821115612a3857612a386128dd565b60006001600160801b0380841680612a7957612a79612930565b92169190910492915050565b6001600160801b03818116838216028082169190828114612aa857612aa86128dd565b505092915050565b6001600160801b03818116838216019080821115612a3857612a386128dd565b60008251612ae281846020870161283c565b919091019291505056fed16483466b463d83139bd6faa077189744e8d5b1ba48b88c0f6d06eda7660ca8a2646970667358221220c5698df8530361251acb57ac533336505e88f1fceebc66dfb14a041a7bd091bd64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d366e016ae0677cdce93472e603b75051e022ad0000000000000000000000000c4cbae499bb4ca41e78f52f07f5d98c375711774000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000335982dae827049d35f09d5ec927de2bc38df3de
-----Decoded View---------------
Arg [0] : _borrowerOperationsAddress (address): 0xd366e016Ae0677CdCE93472e603b75051E022AD0
Arg [1] : _cdpManagerAddress (address): 0xc4cbaE499bb4Ca41E78f52F07f5d98c375711774
Arg [2] : _collTokenAddress (address): 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84
Arg [3] : _collSurplusAddress (address): 0x335982DaE827049d35f09D5ec927De2bc38df3De
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000d366e016ae0677cdce93472e603b75051e022ad0
Arg [1] : 000000000000000000000000c4cbae499bb4ca41e78f52f07f5d98c375711774
Arg [2] : 000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84
Arg [3] : 000000000000000000000000335982dae827049d35f09d5ec927de2bc38df3de
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $2,694.98 | 2,644.6337 | $7,127,235 |
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.