Contract Overview
Contract Name:
BorrowerOperations
Compiler Version
v0.6.11+commit.5ef660b1
// Sources flattened with hardhat v2.18.3 https://hardhat.org // SPDX-License-Identifier: MIT // File contracts/Dependencies/CheckContract.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; contract CheckContract { /** * Check that the account is an already deployed non-destroyed contract. * See: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L12 */ function checkContract(address _account) internal view { require(_account != address(0), "Account cannot be zero address"); uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(_account) } require(size > 0, "Account code size cannot be zero"); } } // File contracts/Dependencies/Initializable.sol // Original license: SPDX_License_Identifier: MIT // solhint-disable-next-line compiler-version pragma solidity 0.6.11; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = _setInitializedVersion(1); if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { _setInitializedVersion(type(uint8).max); } function _setInitializedVersion(uint8 version) private returns (bool) { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level // of initializers, because in other contexts the contract may have been reentered. if (_initializing) { require( version == 1 && !isContract(address(this)), "Initializable: contract is already initialized" ); return false; } else { require(_initialized < version, "Initializable: contract is already initialized"); _initialized = version; return true; } } function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } // File contracts/Dependencies/BaseMath.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; contract BaseMath { uint constant public DECIMAL_PRECISION = 1e18; } // File contracts/Dependencies/console.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; // Buidler's helper contract for console logging library console { address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); function log() internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log()")); ignored; } function logInt(int p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(int)", p0)); ignored; } function logUint(uint p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint)", p0)); ignored; } function logString(string memory p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string)", p0)); ignored; } function logBool(bool p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool)", p0)); ignored; } function logAddress(address p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address)", p0)); ignored; } function logBytes(bytes memory p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes)", p0)); ignored; } function logByte(byte p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(byte)", p0)); ignored; } function logBytes1(bytes1 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes1)", p0)); ignored; } function logBytes2(bytes2 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes2)", p0)); ignored; } function logBytes3(bytes3 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes3)", p0)); ignored; } function logBytes4(bytes4 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes4)", p0)); ignored; } function logBytes5(bytes5 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes5)", p0)); ignored; } function logBytes6(bytes6 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes6)", p0)); ignored; } function logBytes7(bytes7 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes7)", p0)); ignored; } function logBytes8(bytes8 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes8)", p0)); ignored; } function logBytes9(bytes9 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes9)", p0)); ignored; } function logBytes10(bytes10 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes10)", p0)); ignored; } function logBytes11(bytes11 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes11)", p0)); ignored; } function logBytes12(bytes12 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes12)", p0)); ignored; } function logBytes13(bytes13 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes13)", p0)); ignored; } function logBytes14(bytes14 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes14)", p0)); ignored; } function logBytes15(bytes15 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes15)", p0)); ignored; } function logBytes16(bytes16 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes16)", p0)); ignored; } function logBytes17(bytes17 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes17)", p0)); ignored; } function logBytes18(bytes18 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes18)", p0)); ignored; } function logBytes19(bytes19 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes19)", p0)); ignored; } function logBytes20(bytes20 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes20)", p0)); ignored; } function logBytes21(bytes21 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes21)", p0)); ignored; } function logBytes22(bytes22 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes22)", p0)); ignored; } function logBytes23(bytes23 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes23)", p0)); ignored; } function logBytes24(bytes24 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes24)", p0)); ignored; } function logBytes25(bytes25 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes25)", p0)); ignored; } function logBytes26(bytes26 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes26)", p0)); ignored; } function logBytes27(bytes27 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes27)", p0)); ignored; } function logBytes28(bytes28 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes28)", p0)); ignored; } function logBytes29(bytes29 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes29)", p0)); ignored; } function logBytes30(bytes30 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes30)", p0)); ignored; } function logBytes31(bytes31 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes31)", p0)); ignored; } function logBytes32(bytes32 p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bytes32)", p0)); ignored; } function log(uint p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint)", p0)); ignored; } function log(string memory p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string)", p0)); ignored; } function log(bool p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool)", p0)); ignored; } function log(address p0) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address)", p0)); ignored; } function log(uint p0, uint p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint)", p0, p1)); ignored; } function log(uint p0, string memory p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string)", p0, p1)); ignored; } function log(uint p0, bool p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool)", p0, p1)); ignored; } function log(uint p0, address p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address)", p0, p1)); ignored; } function log(string memory p0, uint p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint)", p0, p1)); ignored; } function log(string memory p0, string memory p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string)", p0, p1)); ignored; } function log(string memory p0, bool p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool)", p0, p1)); ignored; } function log(string memory p0, address p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address)", p0, p1)); ignored; } function log(bool p0, uint p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint)", p0, p1)); ignored; } function log(bool p0, string memory p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string)", p0, p1)); ignored; } function log(bool p0, bool p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool)", p0, p1)); ignored; } function log(bool p0, address p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address)", p0, p1)); ignored; } function log(address p0, uint p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint)", p0, p1)); ignored; } function log(address p0, string memory p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string)", p0, p1)); ignored; } function log(address p0, bool p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool)", p0, p1)); ignored; } function log(address p0, address p1) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address)", p0, p1)); ignored; } function log(uint p0, uint p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); ignored; } function log(uint p0, uint p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); ignored; } function log(uint p0, uint p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); ignored; } function log(uint p0, uint p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); ignored; } function log(uint p0, string memory p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); ignored; } function log(uint p0, string memory p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); ignored; } function log(uint p0, string memory p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); ignored; } function log(uint p0, string memory p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); ignored; } function log(uint p0, bool p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); ignored; } function log(uint p0, bool p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); ignored; } function log(uint p0, bool p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); ignored; } function log(uint p0, bool p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); ignored; } function log(uint p0, address p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); ignored; } function log(uint p0, address p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); ignored; } function log(uint p0, address p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); ignored; } function log(uint p0, address p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); ignored; } function log(string memory p0, uint p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); ignored; } function log(string memory p0, uint p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); ignored; } function log(string memory p0, uint p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); ignored; } function log(string memory p0, uint p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); ignored; } function log(string memory p0, string memory p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); ignored; } function log(string memory p0, string memory p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); ignored; } function log(string memory p0, string memory p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); ignored; } function log(string memory p0, string memory p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); ignored; } function log(string memory p0, bool p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); ignored; } function log(string memory p0, bool p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); ignored; } function log(string memory p0, bool p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); ignored; } function log(string memory p0, bool p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); ignored; } function log(string memory p0, address p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); ignored; } function log(string memory p0, address p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); ignored; } function log(string memory p0, address p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); ignored; } function log(string memory p0, address p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); ignored; } function log(bool p0, uint p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); ignored; } function log(bool p0, uint p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); ignored; } function log(bool p0, uint p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); ignored; } function log(bool p0, uint p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); ignored; } function log(bool p0, string memory p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); ignored; } function log(bool p0, string memory p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); ignored; } function log(bool p0, string memory p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); ignored; } function log(bool p0, string memory p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); ignored; } function log(bool p0, bool p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); ignored; } function log(bool p0, bool p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); ignored; } function log(bool p0, bool p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); ignored; } function log(bool p0, bool p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); ignored; } function log(bool p0, address p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); ignored; } function log(bool p0, address p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); ignored; } function log(bool p0, address p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); ignored; } function log(bool p0, address p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); ignored; } function log(address p0, uint p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); ignored; } function log(address p0, uint p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); ignored; } function log(address p0, uint p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); ignored; } function log(address p0, uint p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); ignored; } function log(address p0, string memory p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); ignored; } function log(address p0, string memory p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); ignored; } function log(address p0, string memory p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); ignored; } function log(address p0, string memory p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); ignored; } function log(address p0, bool p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); ignored; } function log(address p0, bool p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); ignored; } function log(address p0, bool p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); ignored; } function log(address p0, bool p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); ignored; } function log(address p0, address p1, uint p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); ignored; } function log(address p0, address p1, string memory p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); ignored; } function log(address p0, address p1, bool p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); ignored; } function log(address p0, address p1, address p2) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); ignored; } function log(uint p0, uint p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, uint p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, string memory p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, bool p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); ignored; } function log(uint p0, address p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, uint p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, string memory p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, bool p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); ignored; } function log(string memory p0, address p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, uint p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, string memory p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, bool p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); ignored; } function log(bool p0, address p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, uint p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, string memory p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, bool p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, uint p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, uint p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, uint p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, uint p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, string memory p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, string memory p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, string memory p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, string memory p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, bool p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, bool p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, bool p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, bool p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, address p2, uint p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, address p2, string memory p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, address p2, bool p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); ignored; } function log(address p0, address p1, address p2, address p3) internal view { (bool ignored, ) = CONSOLE_ADDRESS.staticcall(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); ignored; } } // File contracts/Dependencies/SafeMath.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; /** * Based on OpenZeppelin's SafeMath: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol * * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File contracts/Dependencies/LiquityMath.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; library LiquityMath { using SafeMath for uint; uint internal constant DECIMAL_PRECISION = 1e18; /* 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. * */ uint internal constant NICR_PRECISION = 1e20; function _min(uint _a, uint _b) internal pure returns (uint) { return (_a < _b) ? _a : _b; } function _max(uint _a, uint _b) internal pure returns (uint) { return (_a >= _b) ? _a : _b; } /* * 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(uint x, uint y) internal pure returns (uint decProd) { uint prod_xy = x.mul(y); decProd = prod_xy.add(DECIMAL_PRECISION / 2).div(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) TroveManager._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(uint _base, uint _minutes) internal pure returns (uint) { if (_minutes > 525600000) {_minutes = 525600000;} // cap to avoid overflow if (_minutes == 0) {return DECIMAL_PRECISION;} uint y = DECIMAL_PRECISION; uint x = _base; uint n = _minutes; // Exponentiation-by-squaring while (n > 1) { if (n % 2 == 0) { x = decMul(x, x); n = n.div(2); } else { // if (n % 2 != 0) y = decMul(x, y); x = decMul(x, x); n = (n.sub(1)).div(2); } } return decMul(x, y); } function _getAbsoluteDifference(uint _a, uint _b) internal pure returns (uint) { return (_a >= _b) ? _a.sub(_b) : _b.sub(_a); } function _computeNominalCR(uint _coll, uint _debt) internal pure returns (uint) { if (_debt > 0) { return _coll.mul(NICR_PRECISION).div(_debt); } // Return the maximal value for uint256 if the Trove has a debt of 0. Represents "infinite" CR. else { // if (_debt == 0) return 2**256 - 1; } } function _computeCR(uint _coll, uint _debt, uint _price) internal pure returns (uint) { if (_debt > 0) { uint newCollRatio = _coll.mul(_price).div(_debt); return newCollRatio; } // Return the maximal value for uint256 if the Trove has a debt of 0. Represents "infinite" CR. else { // if (_debt == 0) return 2**256 - 1; } } } // File contracts/Interfaces/IPool.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; // Common interface for the Pools. interface IPool { // --- Events --- event ETHBalanceUpdated(uint _newBalance); event LUSDBalanceUpdated(uint _newBalance); event ActivePoolAddressChanged(address _newActivePoolAddress); event DefaultPoolAddressChanged(address _newDefaultPoolAddress); event StabilityPoolAddressChanged(address _newStabilityPoolAddress); event EtherSent(address _to, uint _amount); // --- Functions --- function getETH() external view returns (uint); function getLUSDDebt() external view returns (uint); function increaseLUSDDebt(uint _amount) external; function decreaseLUSDDebt(uint _amount) external; } // File contracts/Interfaces/IActivePool.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; interface IActivePool is IPool { // --- Events --- event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event TroveManagerAddressChanged(address _newTroveManagerAddress); event ActivePoolLUSDDebtUpdated(uint _LUSDDebt); event ActivePoolETHBalanceUpdated(uint _ETH); // --- Functions --- function sendETH(address _account, uint _amount) external; } // File contracts/Interfaces/IDefaultPool.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; interface IDefaultPool is IPool { // --- Events --- event TroveManagerAddressChanged(address _newTroveManagerAddress); event DefaultPoolLUSDDebtUpdated(uint _LUSDDebt); event DefaultPoolETHBalanceUpdated(uint _ETH); // --- Functions --- function sendETHToActivePool(uint _amount) external; } // File contracts/Interfaces/IPriceFeed.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; interface IPriceFeed { // --- Events --- event LastGoodPriceUpdated(uint _lastGoodPrice); // --- Function --- function fetchPrice() external returns (uint); } // File contracts/Interfaces/ILiquityBase.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; interface ILiquityBase { function priceFeed() external view returns (IPriceFeed); } // File contracts/Dependencies/LiquityBase.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; /* * Base contract for TroveManager, BorrowerOperations and StabilityPool. Contains global system constants and * common functions. */ contract LiquityBase is BaseMath, ILiquityBase { using SafeMath for uint; uint constant public _100pct = 1000000000000000000; // 1e18 == 100% // Minimum collateral ratio for individual troves uint constant public MCR = 1300000000000000000; // 130% // Critical system collateral ratio. If the system's total collateral ratio (TCR) falls below the CCR, Recovery Mode is triggered. uint constant public CCR = 1500000000000000000; // 150% // Amount of LUSD to be locked in gas pool on opening troves uint constant public LUSD_GAS_COMPENSATION = 1e18; // Minimum amount of net LUSD debt a trove must have uint constant public MIN_NET_DEBT = 100e18; uint constant public PERCENT_DIVISOR = 200; // dividing by 200 yields 0.5% uint constant public BORROWING_FEE_FLOOR = DECIMAL_PRECISION / 1000 * 5; // 0.5% IActivePool public activePool; IDefaultPool public defaultPool; IPriceFeed public override priceFeed; // --- Gas compensation functions --- // Returns the composite debt (drawn debt + gas compensation) of a trove, for the purpose of ICR calculation function _getCompositeDebt(uint _debt) internal pure returns (uint) { return _debt.add(LUSD_GAS_COMPENSATION); } function _getNetDebt(uint _debt) internal pure returns (uint) { return _debt.sub(LUSD_GAS_COMPENSATION); } // Return the amount of ETH to be drawn from a trove's collateral and sent as gas compensation. function _getCollGasCompensation(uint _entireColl) internal pure returns (uint) { return _entireColl / PERCENT_DIVISOR; } function getEntireSystemColl() public view returns (uint entireSystemColl) { uint activeColl = activePool.getETH(); uint liquidatedColl = defaultPool.getETH(); return activeColl.add(liquidatedColl); } function getEntireSystemDebt() public view returns (uint entireSystemDebt) { uint activeDebt = activePool.getLUSDDebt(); uint closedDebt = defaultPool.getLUSDDebt(); return activeDebt.add(closedDebt); } function _getTCR(uint _price) internal view returns (uint TCR) { uint entireSystemColl = getEntireSystemColl(); uint entireSystemDebt = getEntireSystemDebt(); TCR = LiquityMath._computeCR(entireSystemColl, entireSystemDebt, _price); return TCR; } function _checkRecoveryMode(uint _price) internal view returns (bool) { uint TCR = _getTCR(_price); return TCR < CCR; } function _requireUserAcceptsFee(uint _fee, uint _amount, uint _maxFeePercentage) internal pure { uint feePercentage = _fee.mul(DECIMAL_PRECISION).div(_amount); require(feePercentage <= _maxFeePercentage, "Fee exceeded provided maximum"); } } // File contracts/Dependencies/OwnableUpgradeable.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; /** * Based on OpenZeppelin's Ownable contract: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol * * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable { address private _owner; address private _pendingOwner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); function __Ownable_init() internal { address msgSender = msg.sender; _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. * * NOTE: This function is not safe, as it doesn’t check owner is calling it. * Make sure you check it before calling it. */ function _renounceOwnership() internal { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { delete _pendingOwner; address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() external { address sender = msg.sender; require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File contracts/Interfaces/IBorrowerOperations.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; // Common interface for the Trove Manager. interface IBorrowerOperations { // --- Events --- event TroveManagerAddressChanged(address _newTroveManagerAddress); event ActivePoolAddressChanged(address _activePoolAddress); event DefaultPoolAddressChanged(address _defaultPoolAddress); event StabilityPoolAddressChanged(address _stabilityPoolAddress); event GasPoolAddressChanged(address _gasPoolAddress); event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress); event PriceFeedAddressChanged(address _newPriceFeedAddress); event SortedTrovesAddressChanged(address _sortedTrovesAddress); event LUSDTokenAddressChanged(address _lusdTokenAddress); event LQTYStakingAddressChanged(address _lqtyStakingAddress); event TroveCreated(address indexed _borrower, uint arrayIndex); event TroveUpdated(address indexed _borrower, uint _debt, uint _coll, uint stake, uint8 operation); event LUSDBorrowingFeePaid(address indexed _borrower, uint _LUSDFee); // --- Functions --- function setAddresses( address _troveManagerAddress, address _activePoolAddress, address _defaultPoolAddress, address _stabilityPoolAddress, address _gasPoolAddress, address _collSurplusPoolAddress, address _priceFeedAddress, address _sortedTrovesAddress, address _lusdTokenAddress, address _lqtyStakingAddress ) external; function openTrove(uint _maxFee, uint _LUSDAmount, address _upperHint, address _lowerHint) external payable; function addColl(address _upperHint, address _lowerHint) external payable; function moveETHGainToTrove(address _user, address _upperHint, address _lowerHint) external payable; function withdrawColl(uint _amount, address _upperHint, address _lowerHint) external; function withdrawLUSD(uint _maxFee, uint _amount, address _upperHint, address _lowerHint) external; function repayLUSD(uint _amount, address _upperHint, address _lowerHint) external; function closeTroveOnBehalf(address troveOwner) external; function closeTrove() external; function adjustTrove(uint _maxFee, uint _collWithdrawal, uint _debtChange, bool isDebtIncrease, address _upperHint, address _lowerHint) external payable; function claimCollateral() external; function getCompositeDebt(uint _debt) external pure returns (uint); } // File contracts/Interfaces/ICollSurplusPool.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; interface ICollSurplusPool { // --- Events --- event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event TroveManagerAddressChanged(address _newTroveManagerAddress); event ActivePoolAddressChanged(address _newActivePoolAddress); event CollBalanceUpdated(address indexed _account, uint _newBalance); event EtherSent(address _to, uint _amount); // --- Contract setters --- function setAddresses( address _borrowerOperationsAddress, address _troveManagerAddress, address _activePoolAddress ) external; function getETH() external view returns (uint); function getCollateral(address _account) external view returns (uint); function accountSurplus(address _account, uint _amount) external; function claimColl(address _account) external; } // File contracts/Dependencies/IERC20.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; /** * 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); } // File contracts/Dependencies/IERC2612.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; /** * @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 uint(-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); } // File contracts/Interfaces/ILUSDToken.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; interface ILUSDToken is IERC20, IERC2612 { // --- Events --- event TroveManagerAddressChanged(address _troveManagerAddress); event StabilityPoolAddressChanged(address _newStabilityPoolAddress); event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event LUSDTokenBalanceUpdated(address _user, uint _amount); // --- Functions --- function mint(address _account, uint256 _amount) external; function burn(address _account, uint256 _amount) external; function sendToPool(address _sender, address poolAddress, uint256 _amount) external; function returnFromPool(address poolAddress, address user, uint256 _amount ) external; } // File contracts/Interfaces/ISortedTroves.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; // Common interface for the SortedTroves Doubly Linked List. interface ISortedTroves { // --- Events --- event SortedTrovesAddressChanged(address _sortedDoublyLLAddress); event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress); event NodeAdded(address _id, uint _NICR); event NodeRemoved(address _id); // --- Functions --- function setParams(uint256 _size, address _TroveManagerAddress, address _borrowerOperationsAddress) external; function insert(address _id, uint256 _ICR, address _prevId, address _nextId) external; function remove(address _id) external; function reInsert(address _id, uint256 _newICR, address _prevId, address _nextId) external; function contains(address _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 (address); function getLast() external view returns (address); function getNext(address _id) external view returns (address); function getPrev(address _id) external view returns (address); function validInsertPosition(uint256 _ICR, address _prevId, address _nextId) external view returns (bool); function findInsertPosition(uint256 _ICR, address _prevId, address _nextId) external view returns (address, address); } // File contracts/Interfaces/IStabilityPool.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; /* * The Stability Pool holds LUSD tokens deposited by Stability Pool depositors. * * When a trove is liquidated, then depending on system conditions, some of its LUSD debt gets offset with * LUSD in the Stability Pool: that is, the offset debt evaporates, and an equal amount of LUSD tokens in the Stability Pool is burned. * * Thus, a liquidation causes each depositor to receive a LUSD loss, in proportion to their deposit as a share of total deposits. * They also receive an ETH gain, as the ETH collateral of the liquidated trove is distributed among Stability depositors, * in the same proportion. * * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40% * of the total LUSD in the Stability Pool, depletes 40% of each deposit. * * A deposit that has experienced a series of liquidations is termed a "compounded deposit": each liquidation depletes the deposit, * multiplying it by some factor in range ]0,1[ * * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / ETH gain derivations: * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf * * --- LQTY ISSUANCE TO STABILITY POOL DEPOSITORS --- * * An LQTY issuance event occurs at every deposit operation, and every liquidation. * * Each deposit is tagged with the address of the front end through which it was made. * * All deposits earn a share of the issued LQTY in proportion to the deposit as a share of total deposits. The LQTY earned * by a given deposit, is split between the depositor and the front end through which the deposit was made, based on the front end's kickbackRate. * * Please see the system Readme for an overview: * https://github.com/liquity/dev/blob/main/README.md#lqty-issuance-to-stability-providers */ interface IStabilityPool { // --- Events --- event StabilityPoolETHBalanceUpdated(uint _newBalance); event StabilityPoolLUSDBalanceUpdated(uint _newBalance); event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event TroveManagerAddressChanged(address _newTroveManagerAddress); event ActivePoolAddressChanged(address _newActivePoolAddress); event DefaultPoolAddressChanged(address _newDefaultPoolAddress); event LUSDTokenAddressChanged(address _newLUSDTokenAddress); event SortedTrovesAddressChanged(address _newSortedTrovesAddress); event PriceFeedAddressChanged(address _newPriceFeedAddress); event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress); event P_Updated(uint _P); event S_Updated(uint _S, uint128 _epoch, uint128 _scale); event G_Updated(uint _G, uint128 _epoch, uint128 _scale); event EpochUpdated(uint128 _currentEpoch); event ScaleUpdated(uint128 _currentScale); event FrontEndRegistered(address indexed _frontEnd, uint _kickbackRate); event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd); event DepositSnapshotUpdated(address indexed _depositor, uint _P, uint _S, uint _G); event FrontEndSnapshotUpdated(address indexed _frontEnd, uint _P, uint _G); event UserDepositChanged(address indexed _depositor, uint _newDeposit); event FrontEndStakeChanged(address indexed _frontEnd, uint _newFrontEndStake, address _depositor); event ETHGainWithdrawn(address indexed _depositor, uint _ETH, uint _LUSDLoss); event LQTYPaidToDepositor(address indexed _depositor, uint _LQTY); event LQTYPaidToFrontEnd(address indexed _frontEnd, uint _LQTY); event EtherSent(address _to, uint _amount); // --- Functions --- /* * Called only once on init, to set addresses of other Liquity contracts * Callable only by owner, renounces ownership at the end */ function setAddresses( address _borrowerOperationsAddress, address _troveManagerAddress, address _activePoolAddress, address _lusdTokenAddress, address _sortedTrovesAddress, address _priceFeedAddress, address _communityIssuanceAddress ) external; /* * Initial checks: * - Frontend is registered or zero address * - Sender is not a registered frontend * - _amount is not zero * --- * - Triggers a LQTY issuance, based on time passed since the last issuance. The LQTY issuance is shared between *all* depositors and front ends * - Tags the deposit with the provided front end tag param, if it's a new deposit * - Sends depositor's accumulated gains (LQTY, ETH) to depositor * - Sends the tagged front end's accumulated LQTY gains to the tagged front end * - Increases deposit and tagged front end's stake, and takes new snapshots for each. */ function provideToSP(uint _amount, address _frontEndTag) external; /* * Initial checks: * - _amount is zero or there are no under collateralized troves left in the system * - User has a non zero deposit * --- * - Triggers a LQTY issuance, based on time passed since the last issuance. The LQTY issuance is shared between *all* depositors and front ends * - Removes the deposit's front end tag if it is a full withdrawal * - Sends all depositor's accumulated gains (LQTY, ETH) to depositor * - Sends the tagged front end's accumulated LQTY gains to the tagged front end * - Decreases deposit and tagged front end's stake, and takes new snapshots for each. * * If _amount > userDeposit, the user withdraws all of their compounded deposit. */ function withdrawFromSP(uint _amount) external; /* * Initial checks: * - User has a non zero deposit * - User has an open trove * - User has some ETH gain * --- * - Triggers a LQTY issuance, based on time passed since the last issuance. The LQTY issuance is shared between *all* depositors and front ends * - Sends all depositor's LQTY gain to depositor * - Sends all tagged front end's LQTY gain to the tagged front end * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove * - Leaves their compounded deposit in the Stability Pool * - Updates snapshots for deposit and tagged front end stake */ function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external; /* * Initial checks: * - Frontend (sender) not already registered * - User (sender) has no deposit * - _kickbackRate is in the range [0, 100%] * --- * Front end makes a one-time selection of kickback rate upon registering */ function registerFrontEnd(uint _kickbackRate) external; /* * Initial checks: * - Caller is TroveManager * --- * Cancels out the specified debt against the LUSD contained in the Stability Pool (as far as possible) * and transfers the Trove's ETH collateral from ActivePool to StabilityPool. * Only called by liquidation functions in the TroveManager. */ function offset(uint _debt, uint _coll) external; /* * Returns the total amount of ETH held by the pool, accounted in an internal variable instead of `balance`, * to exclude edge cases like ETH received from a self-destruct. */ function getETH() external view returns (uint); /* * Returns LUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset. */ function getTotalLUSDDeposits() external view returns (uint); /* * Calculates the ETH gain earned by the deposit since its last snapshots were taken. */ function getDepositorETHGain(address _depositor) external view returns (uint); /* * Calculate the LQTY gain earned by a deposit since its last snapshots were taken. * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned. * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through * which they made their deposit. */ function getDepositorLQTYGain(address _depositor) external view returns (uint); /* * Return the LQTY gain earned by the front end. */ function getFrontEndLQTYGain(address _frontEnd) external view returns (uint); /* * Return the user's compounded deposit. */ function getCompoundedLUSDDeposit(address _depositor) external view returns (uint); /* * Return the front end's compounded stake. * * The front end's compounded stake is equal to the sum of its depositors' compounded deposits. */ function getCompoundedFrontEndStake(address _frontEnd) external view returns (uint); /* * Fallback function * Only callable by Active Pool, it just accounts for ETH received * receive() external payable; */ } // File contracts/Interfaces/ITroveManager.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; // Common interface for the Trove Manager. interface ITroveManager is ILiquityBase { // --- Events --- event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event PriceFeedAddressChanged(address _newPriceFeedAddress); event LUSDTokenAddressChanged(address _newLUSDTokenAddress); event ActivePoolAddressChanged(address _activePoolAddress); event DefaultPoolAddressChanged(address _defaultPoolAddress); event StabilityPoolAddressChanged(address _stabilityPoolAddress); event GasPoolAddressChanged(address _gasPoolAddress); event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress); event SortedTrovesAddressChanged(address _sortedTrovesAddress); event LQTYStakingAddressChanged(address _lqtyStakingAddress); event Liquidation(uint _liquidatedDebt, uint _liquidatedColl, uint _collGasCompensation, uint _LUSDGasCompensation); event Redemption(uint _attemptedLUSDAmount, uint _actualLUSDAmount, uint _ETHSent, uint _ETHFee); event TroveUpdated(address indexed _borrower, uint _debt, uint _coll, uint stake, uint8 operation); event TroveLiquidated(address indexed _borrower, uint _debt, uint _coll, uint8 operation); event BaseRateUpdated(uint _baseRate); event LastFeeOpTimeUpdated(uint _lastFeeOpTime); event TotalStakesUpdated(uint _newTotalStakes); event SystemSnapshotsUpdated(uint _totalStakesSnapshot, uint _totalCollateralSnapshot); event LTermsUpdated(uint _L_ETH, uint _L_LUSDDebt); event TroveSnapshotsUpdated(uint _L_ETH, uint _L_LUSDDebt); event TroveIndexUpdated(address _borrower, uint _newIndex); // --- Functions --- function setAddresses( address _borrowerOperationsAddress, address _activePoolAddress, address _defaultPoolAddress, address _stabilityPoolAddress, address _gasPoolAddress, address _collSurplusPoolAddress, address _priceFeedAddress, address _lusdTokenAddress, address _sortedTrovesAddress, address _lqtyTokenAddress, address _lqtyStakingAddress ) external; function stabilityPool() external view returns (IStabilityPool); function lusdToken() external view returns (ILUSDToken); function getTroveOwnersCount() external view returns (uint); function getTroveFromTroveOwnersArray(uint _index) external view returns (address); function getNominalICR(address _borrower) external view returns (uint); function getCurrentICR(address _borrower, uint _price) external view returns (uint); function liquidate(address _borrower) external; function liquidateTroves(uint _n) external; function batchLiquidateTroves(address[] calldata _troveArray) external; function redeemCollateral( uint _LUSDAmount, address _firstRedemptionHint, address _upperPartialRedemptionHint, address _lowerPartialRedemptionHint, uint _partialRedemptionHintNICR, uint _maxIterations, uint _maxFee ) external; function updateStakeAndTotalStakes(address _borrower) external returns (uint); function updateTroveRewardSnapshots(address _borrower) external; function addTroveOwnerToArray(address _borrower) external returns (uint index); function applyPendingRewards(address _borrower) external; function getPendingETHReward(address _borrower) external view returns (uint); function getPendingLUSDDebtReward(address _borrower) external view returns (uint); function hasPendingRewards(address _borrower) external view returns (bool); function getEntireDebtAndColl(address _borrower) external view returns ( uint debt, uint coll, uint pendingLUSDDebtReward, uint pendingETHReward ); function closeTrove(address _borrower) external; function removeStake(address _borrower) external; function getRedemptionRate() external view returns (uint); function getRedemptionRateWithDecay() external view returns (uint); function getRedemptionFeeWithDecay(uint _ETHDrawn) external view returns (uint); function getBorrowingRate() external view returns (uint); function getBorrowingRateWithDecay() external view returns (uint); function getBorrowingFee(uint LUSDDebt) external view returns (uint); function getBorrowingFeeWithDecay(uint _LUSDDebt) external view returns (uint); function decayBaseRateFromBorrowing() external; function getTroveStatus(address _borrower) external view returns (uint); function getTroveStake(address _borrower) external view returns (uint); function getTroveDebt(address _borrower) external view returns (uint); function getTroveColl(address _borrower) external view returns (uint); function setTroveStatus(address _borrower, uint num) external; function increaseTroveColl(address _borrower, uint _collIncrease) external returns (uint); function decreaseTroveColl(address _borrower, uint _collDecrease) external returns (uint); function increaseTroveDebt(address _borrower, uint _debtIncrease) external returns (uint); function decreaseTroveDebt(address _borrower, uint _collDecrease) external returns (uint); function getTCR(uint _price) external view returns (uint); function checkRecoveryMode(uint _price) external view returns (bool); } // File contracts/BorrowerOperations.sol // Original license: SPDX_License_Identifier: MIT pragma solidity 0.6.11; contract BorrowerOperations is LiquityBase, OwnableUpgradeable, CheckContract, Initializable, IBorrowerOperations { string constant public NAME = "BorrowerOperations"; // --- Connected contract declarations --- ITroveManager public troveManager; address stabilityPoolAddress; address gasPoolAddress; ICollSurplusPool collSurplusPool; address public lqtyStakingAddress; ILUSDToken public lusdToken; // A doubly linked list of Troves, sorted by their collateral ratios ISortedTroves public sortedTroves; /* --- Variable container structs --- Used to hold, return and assign variables inside a function, in order to avoid the error: "CompilerError: Stack too deep". */ struct LocalVariables_adjustTrove { uint price; uint collChange; uint netDebtChange; bool isCollIncrease; uint debt; uint coll; uint oldICR; uint newICR; uint newTCR; uint LUSDFee; uint newDebt; uint newColl; uint stake; } struct LocalVariables_openTrove { uint price; uint LUSDFee; uint netDebt; uint compositeDebt; uint ICR; uint NICR; uint stake; uint arrayIndex; } struct ContractsCache { ITroveManager troveManager; IActivePool activePool; ILUSDToken lusdToken; } enum BorrowerOperation { openTrove, closeTrove, adjustTrove } event TroveManagerAddressChanged(address _newTroveManagerAddress); event ActivePoolAddressChanged(address _activePoolAddress); event DefaultPoolAddressChanged(address _defaultPoolAddress); event StabilityPoolAddressChanged(address _stabilityPoolAddress); event GasPoolAddressChanged(address _gasPoolAddress); event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress); event PriceFeedAddressChanged(address _newPriceFeedAddress); event SortedTrovesAddressChanged(address _sortedTrovesAddress); event LUSDTokenAddressChanged(address _lusdTokenAddress); event LQTYStakingAddressChanged(address _lqtyStakingAddress); event TroveCreated(address indexed _borrower, uint arrayIndex); event TroveUpdated(address indexed _borrower, uint _debt, uint _coll, uint stake, BorrowerOperation operation); event LUSDBorrowingFeePaid(address indexed _borrower, uint _LUSDFee); constructor() public { _disableInitializers(); } function initialize() initializer external { __Ownable_init(); } // --- Dependency setters --- function setAddresses( address _troveManagerAddress, address _activePoolAddress, address _defaultPoolAddress, address _stabilityPoolAddress, address _gasPoolAddress, address _collSurplusPoolAddress, address _priceFeedAddress, address _sortedTrovesAddress, address _lusdTokenAddress, address _lqtyStakingAddress ) external override onlyOwner { // This makes impossible to open a trove with zero withdrawn LUSD assert(MIN_NET_DEBT > 0); checkContract(_troveManagerAddress); checkContract(_activePoolAddress); checkContract(_defaultPoolAddress); checkContract(_stabilityPoolAddress); checkContract(_gasPoolAddress); checkContract(_collSurplusPoolAddress); checkContract(_priceFeedAddress); checkContract(_sortedTrovesAddress); checkContract(_lusdTokenAddress); troveManager = ITroveManager(_troveManagerAddress); activePool = IActivePool(_activePoolAddress); defaultPool = IDefaultPool(_defaultPoolAddress); stabilityPoolAddress = _stabilityPoolAddress; gasPoolAddress = _gasPoolAddress; collSurplusPool = ICollSurplusPool(_collSurplusPoolAddress); priceFeed = IPriceFeed(_priceFeedAddress); sortedTroves = ISortedTroves(_sortedTrovesAddress); lusdToken = ILUSDToken(_lusdTokenAddress); lqtyStakingAddress = _lqtyStakingAddress; emit TroveManagerAddressChanged(_troveManagerAddress); emit ActivePoolAddressChanged(_activePoolAddress); emit DefaultPoolAddressChanged(_defaultPoolAddress); emit StabilityPoolAddressChanged(_stabilityPoolAddress); emit GasPoolAddressChanged(_gasPoolAddress); emit CollSurplusPoolAddressChanged(_collSurplusPoolAddress); emit PriceFeedAddressChanged(_priceFeedAddress); emit SortedTrovesAddressChanged(_sortedTrovesAddress); emit LUSDTokenAddressChanged(_lusdTokenAddress); emit LQTYStakingAddressChanged(_lqtyStakingAddress); } // --- Borrower Trove Operations --- function openTrove(uint _maxFeePercentage, uint _LUSDAmount, address _upperHint, address _lowerHint) external payable override { ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, lusdToken); LocalVariables_openTrove memory vars; vars.price = priceFeed.fetchPrice(); bool isRecoveryMode = _checkRecoveryMode(vars.price); _requireValidMaxFeePercentage(_maxFeePercentage, isRecoveryMode); _requireTroveisNotActive(contractsCache.troveManager, msg.sender); vars.LUSDFee; vars.netDebt = _LUSDAmount; if (!isRecoveryMode) { vars.LUSDFee = _triggerBorrowingFee(contractsCache.troveManager, contractsCache.lusdToken, _LUSDAmount, _maxFeePercentage); vars.netDebt = vars.netDebt.add(vars.LUSDFee); } _requireAtLeastMinNetDebt(vars.netDebt); // ICR is based on the composite debt, i.e. the requested LUSD amount + LUSD borrowing fee + LUSD gas comp. vars.compositeDebt = _getCompositeDebt(vars.netDebt); assert(vars.compositeDebt > 0); vars.ICR = LiquityMath._computeCR(msg.value, vars.compositeDebt, vars.price); vars.NICR = LiquityMath._computeNominalCR(msg.value, vars.compositeDebt); if (isRecoveryMode) { _requireICRisAboveCCR(vars.ICR); } else { _requireICRisAboveMCR(vars.ICR); uint newTCR = _getNewTCRFromTroveChange(msg.value, true, vars.compositeDebt, true, vars.price); // bools: coll increase, debt increase _requireNewTCRisAboveCCR(newTCR); } // Set the trove struct's properties contractsCache.troveManager.setTroveStatus(msg.sender, 1); contractsCache.troveManager.increaseTroveColl(msg.sender, msg.value); contractsCache.troveManager.increaseTroveDebt(msg.sender, vars.compositeDebt); contractsCache.troveManager.updateTroveRewardSnapshots(msg.sender); vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(msg.sender); sortedTroves.insert(msg.sender, vars.NICR, _upperHint, _lowerHint); vars.arrayIndex = contractsCache.troveManager.addTroveOwnerToArray(msg.sender); emit TroveCreated(msg.sender, vars.arrayIndex); // Move the ether to the Active Pool, and mint the LUSDAmount to the borrower _activePoolAddColl(contractsCache.activePool, msg.value); _withdrawLUSD(contractsCache.activePool, contractsCache.lusdToken, msg.sender, _LUSDAmount, vars.netDebt); // Move the LUSD gas compensation to the Gas Pool _withdrawLUSD(contractsCache.activePool, contractsCache.lusdToken, gasPoolAddress, LUSD_GAS_COMPENSATION, LUSD_GAS_COMPENSATION); emit TroveUpdated(msg.sender, vars.compositeDebt, msg.value, vars.stake, BorrowerOperation.openTrove); emit LUSDBorrowingFeePaid(msg.sender, vars.LUSDFee); } // Send ETH as collateral to a trove function addColl(address _upperHint, address _lowerHint) external payable override { _adjustTrove(msg.sender, 0, 0, false, _upperHint, _lowerHint, 0); } // Send ETH as collateral to a trove. Called by only the Stability Pool. function moveETHGainToTrove(address _borrower, address _upperHint, address _lowerHint) external payable override { _requireCallerIsStabilityPool(); _adjustTrove(_borrower, 0, 0, false, _upperHint, _lowerHint, 0); } // Withdraw ETH collateral from a trove function withdrawColl(uint _collWithdrawal, address _upperHint, address _lowerHint) external override { _adjustTrove(msg.sender, _collWithdrawal, 0, false, _upperHint, _lowerHint, 0); } // Withdraw LUSD tokens from a trove: mint new LUSD tokens to the owner, and increase the trove's debt accordingly function withdrawLUSD(uint _maxFeePercentage, uint _LUSDAmount, address _upperHint, address _lowerHint) external override { _adjustTrove(msg.sender, 0, _LUSDAmount, true, _upperHint, _lowerHint, _maxFeePercentage); } // Repay LUSD tokens to a Trove: Burn the repaid LUSD tokens, and reduce the trove's debt accordingly function repayLUSD(uint _LUSDAmount, address _upperHint, address _lowerHint) external override { _adjustTrove(msg.sender, 0, _LUSDAmount, false, _upperHint, _lowerHint, 0); } function adjustTrove(uint _maxFeePercentage, uint _collWithdrawal, uint _LUSDChange, bool _isDebtIncrease, address _upperHint, address _lowerHint) external payable override { _adjustTrove(msg.sender, _collWithdrawal, _LUSDChange, _isDebtIncrease, _upperHint, _lowerHint, _maxFeePercentage); } /* * _adjustTrove(): Alongside a debt change, this function can perform either a collateral top-up or a collateral withdrawal. * * It therefore expects either a positive msg.value, or a positive _collWithdrawal argument. * * If both are positive, it will revert. */ function _adjustTrove(address _borrower, uint _collWithdrawal, uint _LUSDChange, bool _isDebtIncrease, address _upperHint, address _lowerHint, uint _maxFeePercentage) internal { ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, lusdToken); LocalVariables_adjustTrove memory vars; vars.price = priceFeed.fetchPrice(); bool isRecoveryMode = _checkRecoveryMode(vars.price); if (_isDebtIncrease) { _requireValidMaxFeePercentage(_maxFeePercentage, isRecoveryMode); _requireNonZeroDebtChange(_LUSDChange); } _requireSingularCollChange(_collWithdrawal); _requireNonZeroAdjustment(_collWithdrawal, _LUSDChange); _requireTroveisActive(contractsCache.troveManager, _borrower); // Confirm the operation is either a borrower adjusting their own trove, or a pure ETH transfer from the Stability Pool to a trove assert(msg.sender == _borrower || (msg.sender == stabilityPoolAddress && msg.value > 0 && _LUSDChange == 0)); contractsCache.troveManager.applyPendingRewards(_borrower); // Get the collChange based on whether or not ETH was sent in the transaction (vars.collChange, vars.isCollIncrease) = _getCollChange(msg.value, _collWithdrawal); vars.netDebtChange = _LUSDChange; // If the adjustment incorporates a debt increase and system is in Normal Mode, then trigger a borrowing fee if (_isDebtIncrease && !isRecoveryMode) { vars.LUSDFee = _triggerBorrowingFee(contractsCache.troveManager, contractsCache.lusdToken, _LUSDChange, _maxFeePercentage); vars.netDebtChange = vars.netDebtChange.add(vars.LUSDFee); // The raw debt change includes the fee } vars.debt = contractsCache.troveManager.getTroveDebt(_borrower); vars.coll = contractsCache.troveManager.getTroveColl(_borrower); // Get the trove's old ICR before the adjustment, and what its new ICR will be after the adjustment vars.oldICR = LiquityMath._computeCR(vars.coll, vars.debt, vars.price); vars.newICR = _getNewICRFromTroveChange(vars.coll, vars.debt, vars.collChange, vars.isCollIncrease, vars.netDebtChange, _isDebtIncrease, vars.price); assert(_collWithdrawal <= vars.coll); // Check the adjustment satisfies all conditions for the current system mode _requireValidAdjustmentInCurrentMode(isRecoveryMode, _collWithdrawal, _isDebtIncrease, vars); // When the adjustment is a debt repayment, check it's a valid amount and that the caller has enough LUSD if (!_isDebtIncrease && _LUSDChange > 0) { _requireAtLeastMinNetDebt(_getNetDebt(vars.debt).sub(vars.netDebtChange)); _requireValidLUSDRepayment(vars.debt, vars.netDebtChange); _requireSufficientLUSDBalance(contractsCache.lusdToken, _borrower, vars.netDebtChange); } (vars.newColl, vars.newDebt) = _updateTroveFromAdjustment(contractsCache.troveManager, _borrower, vars.collChange, vars.isCollIncrease, vars.netDebtChange, _isDebtIncrease); vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(_borrower); // Re-insert trove in to the sorted list uint newNICR = _getNewNominalICRFromTroveChange(vars.coll, vars.debt, vars.collChange, vars.isCollIncrease, vars.netDebtChange, _isDebtIncrease); sortedTroves.reInsert(_borrower, newNICR, _upperHint, _lowerHint); emit TroveUpdated(_borrower, vars.newDebt, vars.newColl, vars.stake, BorrowerOperation.adjustTrove); emit LUSDBorrowingFeePaid(msg.sender, vars.LUSDFee); // Use the unmodified _LUSDChange here, as we don't send the fee to the user _moveTokensAndETHfromAdjustment( contractsCache.activePool, contractsCache.lusdToken, msg.sender, vars.collChange, vars.isCollIncrease, _LUSDChange, _isDebtIncrease, vars.netDebtChange ); } function closeTroveOnBehalf(address troveOwner) external override { closeTroveInternal(msg.sender, troveOwner); } function closeTrove() external override { closeTroveInternal(msg.sender, msg.sender); } function closeTroveInternal(address repayer, address troveOwner) internal { ITroveManager troveManagerCached = troveManager; IActivePool activePoolCached = activePool; ILUSDToken lusdTokenCached = lusdToken; _requireTroveisActive(troveManagerCached, troveOwner); uint price = priceFeed.fetchPrice(); _requireNotInRecoveryMode(price); troveManagerCached.applyPendingRewards(troveOwner); uint coll = troveManagerCached.getTroveColl(troveOwner); uint debt = troveManagerCached.getTroveDebt(troveOwner); _requireSufficientLUSDBalance(lusdTokenCached, repayer, debt.sub(LUSD_GAS_COMPENSATION)); uint newTCR = _getNewTCRFromTroveChange(coll, false, debt, false, price); _requireNewTCRisAboveCCR(newTCR); troveManagerCached.removeStake(troveOwner); troveManagerCached.closeTrove(troveOwner); emit TroveUpdated(troveOwner, 0, 0, 0, BorrowerOperation.closeTrove); // Burn the repaid LUSD from the user's balance and the gas compensation from the Gas Pool _repayLUSD(activePoolCached, lusdTokenCached, repayer, debt.sub(LUSD_GAS_COMPENSATION)); _repayLUSD(activePoolCached, lusdTokenCached, gasPoolAddress, LUSD_GAS_COMPENSATION); // Send the collateral back to the user activePoolCached.sendETH(troveOwner, coll); } /** * Claim remaining collateral from a redemption or from a liquidation with ICR > MCR in Recovery Mode */ function claimCollateral() external override { // send ETH from CollSurplus Pool to owner collSurplusPool.claimColl(msg.sender); } // --- Helper functions --- function _triggerBorrowingFee(ITroveManager _troveManager, ILUSDToken _lusdToken, uint _LUSDAmount, uint _maxFeePercentage) internal returns (uint) { _troveManager.decayBaseRateFromBorrowing(); // decay the baseRate state variable uint LUSDFee = _troveManager.getBorrowingFee(_LUSDAmount); _requireUserAcceptsFee(LUSDFee, _LUSDAmount, _maxFeePercentage); // Send fee to LQTY staking contract _lusdToken.mint(lqtyStakingAddress, LUSDFee); return LUSDFee; } function _getUSDValue(uint _coll, uint _price) internal pure returns (uint) { uint usdValue = _price.mul(_coll).div(DECIMAL_PRECISION); return usdValue; } function _getCollChange( uint _collReceived, uint _requestedCollWithdrawal ) internal pure returns(uint collChange, bool isCollIncrease) { if (_collReceived != 0) { collChange = _collReceived; isCollIncrease = true; } else { collChange = _requestedCollWithdrawal; } } // Update trove's coll and debt based on whether they increase or decrease function _updateTroveFromAdjustment ( ITroveManager _troveManager, address _borrower, uint _collChange, bool _isCollIncrease, uint _debtChange, bool _isDebtIncrease ) internal returns (uint, uint) { uint newColl = (_isCollIncrease) ? _troveManager.increaseTroveColl(_borrower, _collChange) : _troveManager.decreaseTroveColl(_borrower, _collChange); uint newDebt = (_isDebtIncrease) ? _troveManager.increaseTroveDebt(_borrower, _debtChange) : _troveManager.decreaseTroveDebt(_borrower, _debtChange); return (newColl, newDebt); } function _moveTokensAndETHfromAdjustment ( IActivePool _activePool, ILUSDToken _lusdToken, address _borrower, uint _collChange, bool _isCollIncrease, uint _LUSDChange, bool _isDebtIncrease, uint _netDebtChange ) internal { if (_isDebtIncrease) { _withdrawLUSD(_activePool, _lusdToken, _borrower, _LUSDChange, _netDebtChange); } else { _repayLUSD(_activePool, _lusdToken, _borrower, _LUSDChange); } if (_isCollIncrease) { _activePoolAddColl(_activePool, _collChange); } else { _activePool.sendETH(_borrower, _collChange); } } // Send ETH to Active Pool and increase its recorded ETH balance function _activePoolAddColl(IActivePool _activePool, uint _amount) internal { (bool success, ) = address(_activePool).call{value: _amount}(""); require(success, "BorrowerOps: Sending ETH to ActivePool failed"); } // Issue the specified amount of LUSD to _account and increases the total active debt (_netDebtIncrease potentially includes a LUSDFee) function _withdrawLUSD(IActivePool _activePool, ILUSDToken _lusdToken, address _account, uint _LUSDAmount, uint _netDebtIncrease) internal { _activePool.increaseLUSDDebt(_netDebtIncrease); _lusdToken.mint(_account, _LUSDAmount); } // Burn the specified amount of LUSD from _account and decreases the total active debt function _repayLUSD(IActivePool _activePool, ILUSDToken _lusdToken, address _account, uint _LUSD) internal { _activePool.decreaseLUSDDebt(_LUSD); _lusdToken.burn(_account, _LUSD); } // --- 'Require' wrapper functions --- function _requireSingularCollChange(uint _collWithdrawal) internal view { require(msg.value == 0 || _collWithdrawal == 0, "BorrowerOperations: Cannot withdraw and add coll"); } function _requireCallerIsBorrower(address _borrower) internal view { require(msg.sender == _borrower, "BorrowerOps: Caller must be the borrower for a withdrawal"); } function _requireNonZeroAdjustment(uint _collWithdrawal, uint _LUSDChange) internal view { require(msg.value != 0 || _collWithdrawal != 0 || _LUSDChange != 0, "BorrowerOps: There must be either a collateral change or a debt change"); } function _requireTroveisActive(ITroveManager _troveManager, address _borrower) internal view { uint status = _troveManager.getTroveStatus(_borrower); require(status == 1, "BorrowerOps: Trove does not exist or is closed"); } function _requireTroveisNotActive(ITroveManager _troveManager, address _borrower) internal view { uint status = _troveManager.getTroveStatus(_borrower); require(status != 1, "BorrowerOps: Trove is active"); } function _requireNonZeroDebtChange(uint _LUSDChange) internal pure { require(_LUSDChange > 0, "BorrowerOps: Debt increase requires non-zero debtChange"); } function _requireNotInRecoveryMode(uint _price) internal view { require(!_checkRecoveryMode(_price), "BorrowerOps: Operation not permitted during Recovery Mode"); } function _requireNoCollWithdrawal(uint _collWithdrawal) internal pure { require(_collWithdrawal == 0, "BorrowerOps: Collateral withdrawal not permitted Recovery Mode"); } function _requireValidAdjustmentInCurrentMode ( bool _isRecoveryMode, uint _collWithdrawal, bool _isDebtIncrease, LocalVariables_adjustTrove memory _vars ) internal view { /* *In Recovery Mode, only allow: * * - Pure collateral top-up * - Pure debt repayment * - Collateral top-up with debt repayment * - A debt increase combined with a collateral top-up which makes the ICR >= 150% and improves the ICR (and by extension improves the TCR). * * In Normal Mode, ensure: * * - The new ICR is above MCR * - The adjustment won't pull the TCR below CCR */ if (_isRecoveryMode) { _requireNoCollWithdrawal(_collWithdrawal); if (_isDebtIncrease) { _requireICRisAboveCCR(_vars.newICR); _requireNewICRisAboveOldICR(_vars.newICR, _vars.oldICR); } } else { // if Normal Mode _requireICRisAboveMCR(_vars.newICR); _vars.newTCR = _getNewTCRFromTroveChange(_vars.collChange, _vars.isCollIncrease, _vars.netDebtChange, _isDebtIncrease, _vars.price); _requireNewTCRisAboveCCR(_vars.newTCR); } } function _requireICRisAboveMCR(uint _newICR) internal pure { require(_newICR >= MCR, "BorrowerOps: An operation that would result in ICR < MCR is not permitted"); } function _requireICRisAboveCCR(uint _newICR) internal pure { require(_newICR >= CCR, "BorrowerOps: Operation must leave trove with ICR >= CCR"); } function _requireNewICRisAboveOldICR(uint _newICR, uint _oldICR) internal pure { require(_newICR >= _oldICR, "BorrowerOps: Cannot decrease your Trove's ICR in Recovery Mode"); } function _requireNewTCRisAboveCCR(uint _newTCR) internal pure { require(_newTCR >= CCR, "BorrowerOps: An operation that would result in TCR < CCR is not permitted"); } function _requireAtLeastMinNetDebt(uint _netDebt) internal pure { require (_netDebt >= MIN_NET_DEBT, "BorrowerOps: Trove's net debt must be greater than minimum"); } function _requireValidLUSDRepayment(uint _currentDebt, uint _debtRepayment) internal pure { require(_debtRepayment <= _currentDebt.sub(LUSD_GAS_COMPENSATION), "BorrowerOps: Amount repaid must not be larger than the Trove's debt"); } function _requireCallerIsStabilityPool() internal view { require(msg.sender == stabilityPoolAddress, "BorrowerOps: Caller is not Stability Pool"); } function _requireSufficientLUSDBalance(ILUSDToken _lusdToken, address _borrower, uint _debtRepayment) internal view { require(_lusdToken.balanceOf(_borrower) >= _debtRepayment, "BorrowerOps: Caller doesnt have enough LUSD to make repayment"); } function _requireValidMaxFeePercentage(uint _maxFeePercentage, bool _isRecoveryMode) internal pure { if (_isRecoveryMode) { require(_maxFeePercentage <= DECIMAL_PRECISION, "Max fee percentage must less than or equal to 100%"); } else { require(_maxFeePercentage >= BORROWING_FEE_FLOOR && _maxFeePercentage <= DECIMAL_PRECISION, "Max fee percentage must be between 0.5% and 100%"); } } // --- ICR and TCR getters --- // Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards. function _getNewNominalICRFromTroveChange ( uint _coll, uint _debt, uint _collChange, bool _isCollIncrease, uint _debtChange, bool _isDebtIncrease ) pure internal returns (uint) { (uint newColl, uint newDebt) = _getNewTroveAmounts(_coll, _debt, _collChange, _isCollIncrease, _debtChange, _isDebtIncrease); uint newNICR = LiquityMath._computeNominalCR(newColl, newDebt); return newNICR; } // Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards. function _getNewICRFromTroveChange ( uint _coll, uint _debt, uint _collChange, bool _isCollIncrease, uint _debtChange, bool _isDebtIncrease, uint _price ) pure internal returns (uint) { (uint newColl, uint newDebt) = _getNewTroveAmounts(_coll, _debt, _collChange, _isCollIncrease, _debtChange, _isDebtIncrease); uint newICR = LiquityMath._computeCR(newColl, newDebt, _price); return newICR; } function _getNewTroveAmounts( uint _coll, uint _debt, uint _collChange, bool _isCollIncrease, uint _debtChange, bool _isDebtIncrease ) internal pure returns (uint, uint) { uint newColl = _coll; uint newDebt = _debt; newColl = _isCollIncrease ? _coll.add(_collChange) : _coll.sub(_collChange); newDebt = _isDebtIncrease ? _debt.add(_debtChange) : _debt.sub(_debtChange); return (newColl, newDebt); } function _getNewTCRFromTroveChange ( uint _collChange, bool _isCollIncrease, uint _debtChange, bool _isDebtIncrease, uint _price ) internal view returns (uint) { uint totalColl = getEntireSystemColl(); uint totalDebt = getEntireSystemDebt(); totalColl = _isCollIncrease ? totalColl.add(_collChange) : totalColl.sub(_collChange); totalDebt = _isDebtIncrease ? totalDebt.add(_debtChange) : totalDebt.sub(_debtChange); uint newTCR = LiquityMath._computeCR(totalColl, totalDebt, _price); return newTCR; } function getCompositeDebt(uint _debt) external pure override returns (uint) { return _getCompositeDebt(_debt); } }
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_activePoolAddress","type":"address"}],"name":"ActivePoolAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_collSurplusPoolAddress","type":"address"}],"name":"CollSurplusPoolAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_defaultPoolAddress","type":"address"}],"name":"DefaultPoolAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_gasPoolAddress","type":"address"}],"name":"GasPoolAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_lqtyStakingAddress","type":"address"}],"name":"LQTYStakingAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"_LUSDFee","type":"uint256"}],"name":"LUSDBorrowingFeePaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_lusdTokenAddress","type":"address"}],"name":"LUSDTokenAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newPriceFeedAddress","type":"address"}],"name":"PriceFeedAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sortedTrovesAddress","type":"address"}],"name":"SortedTrovesAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_stabilityPoolAddress","type":"address"}],"name":"StabilityPoolAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"arrayIndex","type":"uint256"}],"name":"TroveCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newTroveManagerAddress","type":"address"}],"name":"TroveManagerAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"_debt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_coll","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stake","type":"uint256"},{"indexed":false,"internalType":"enum BorrowerOperations.BorrowerOperation","name":"operation","type":"uint8"}],"name":"TroveUpdated","type":"event"},{"inputs":[],"name":"BORROWING_FEE_FLOOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CCR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DECIMAL_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LUSD_GAS_COMPENSATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MCR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_NET_DEBT","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":"PERCENT_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_100pct","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"activePool","outputs":[{"internalType":"contract IActivePool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"}],"name":"addColl","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxFeePercentage","type":"uint256"},{"internalType":"uint256","name":"_collWithdrawal","type":"uint256"},{"internalType":"uint256","name":"_LUSDChange","type":"uint256"},{"internalType":"bool","name":"_isDebtIncrease","type":"bool"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"}],"name":"adjustTrove","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"claimCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"closeTrove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"troveOwner","type":"address"}],"name":"closeTroveOnBehalf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultPool","outputs":[{"internalType":"contract IDefaultPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_debt","type":"uint256"}],"name":"getCompositeDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getEntireSystemColl","outputs":[{"internalType":"uint256","name":"entireSystemColl","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEntireSystemDebt","outputs":[{"internalType":"uint256","name":"entireSystemDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lqtyStakingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lusdToken","outputs":[{"internalType":"contract ILUSDToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"}],"name":"moveETHGainToTrove","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxFeePercentage","type":"uint256"},{"internalType":"uint256","name":"_LUSDAmount","type":"uint256"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"}],"name":"openTrove","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceFeed","outputs":[{"internalType":"contract IPriceFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_LUSDAmount","type":"uint256"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"}],"name":"repayLUSD","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_troveManagerAddress","type":"address"},{"internalType":"address","name":"_activePoolAddress","type":"address"},{"internalType":"address","name":"_defaultPoolAddress","type":"address"},{"internalType":"address","name":"_stabilityPoolAddress","type":"address"},{"internalType":"address","name":"_gasPoolAddress","type":"address"},{"internalType":"address","name":"_collSurplusPoolAddress","type":"address"},{"internalType":"address","name":"_priceFeedAddress","type":"address"},{"internalType":"address","name":"_sortedTrovesAddress","type":"address"},{"internalType":"address","name":"_lusdTokenAddress","type":"address"},{"internalType":"address","name":"_lqtyStakingAddress","type":"address"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sortedTroves","outputs":[{"internalType":"contract ISortedTroves","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"troveManager","outputs":[{"internalType":"contract ITroveManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collWithdrawal","type":"uint256"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"}],"name":"withdrawColl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxFeePercentage","type":"uint256"},{"internalType":"uint256","name":"_LUSDAmount","type":"uint256"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"}],"name":"withdrawLUSD","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052600436106101cf5760003560e01c8063795d26c3116100f8578063a3f4df7e11610090578063a3f4df7e1461056b578063ae918754146105f5578063b83f91a21461060a578063c345960c1461061f578063c6a6cf2014610652578063e30c39781461069a578063ea9638bf146106af578063f2fde38b146106e7578063f92d34331461071a576101cf565b8063795d26c31461048a57806379ba50971461049f5780637f7dde4a146104b45780638129fc1c146104c9578063860665b3146104de578063887105d3146105185780638da5cb5b1461052d5780638f32d59b14610542578063a20baee61461029a576101cf565b80635530273c1161016b5780635530273c146103345780635733d58f1461037557806368647db11461038a5780636c37a4af146103b85780636f0b0c1c1461043657806372fe25aa1461029a578063741bef1a1461044b578063761ab22c14610460578063794e572414610475576101cf565b806304491fa7146101d45780630e704d50146102175780631184e5f81461022c5780631bf43555146102735780632e86bbd81461029a5780633cc74225146102af5780633d83908a146102e05780634870dd9a146102f55780634ff814431461030a575b600080fd5b3480156101e057600080fd5b50610215600480360360608110156101f757600080fd5b508035906001600160a01b036020820135811691604001351661072f565b005b34801561022357600080fd5b50610215610746565b34801561023857600080fd5b506102156004803603608081101561024f57600080fd5b508035906020810135906001600160a01b0360408201358116916060013516610752565b34801561027f57600080fd5b50610288610769565b60408051918252519081900360200190f35b3480156102a657600080fd5b50610288610776565b3480156102bb57600080fd5b506102c4610782565b604080516001600160a01b039092168252519081900360200190f35b3480156102ec57600080fd5b506102c4610791565b34801561030157600080fd5b506102886107a6565b34801561031657600080fd5b506102886004803603602081101561032d57600080fd5b50356107ab565b34801561034057600080fd5b506102156004803603606081101561035757600080fd5b508035906001600160a01b03602082013581169160400135166107be565b34801561038157600080fd5b506102886107cf565b610215600480360360408110156103a057600080fd5b506001600160a01b03813581169160200135166107db565b3480156103c457600080fd5b5061021560048036036101408110156103dc57600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135821691608082013581169160a081013582169160c082013581169160e08101358216916101008201358116916101200135166107f1565b34801561044257600080fd5b50610215610b9a565b34801561045757600080fd5b506102c4610bfa565b34801561046c57600080fd5b506102c4610c09565b34801561048157600080fd5b50610288610c18565b34801561049657600080fd5b50610288610c24565b3480156104ab57600080fd5b50610215610d25565b3480156104c057600080fd5b506102c4610d80565b3480156104d557600080fd5b50610215610d8f565b610215600480360360808110156104f457600080fd5b508035906020810135906001600160a01b0360408201358116916060013516610e03565b34801561052457600080fd5b5061028861143d565b34801561053957600080fd5b506102c46114f9565b34801561054e57600080fd5b50610557611508565b604080519115158252519081900360200190f35b34801561057757600080fd5b50610580611519565b6040805160208082528351818301528351919283929083019185019080838360005b838110156105ba5781810151838201526020016105a2565b50505050905090810190601f1680156105e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561060157600080fd5b506102c4611547565b34801561061657600080fd5b506102c4611556565b34801561062b57600080fd5b506102156004803603602081101561064257600080fd5b50356001600160a01b0316611565565b610215600480360360c081101561066857600080fd5b5080359060208101359060408101359060608101351515906001600160a01b03608082013581169160a001351661156f565b3480156106a657600080fd5b506102c4611586565b610215600480360360608110156106c557600080fd5b506001600160a01b038135811691602081013582169160409091013516611595565b3480156106f357600080fd5b506102156004803603602081101561070a57600080fd5b50356001600160a01b03166115af565b34801561072657600080fd5b50610288611666565b61074133600085600086866000611671565b505050565b6107503333611c81565b565b61076333600085600186868a611671565b50505050565b68056bc75e2d6310000081565b670de0b6b3a764000081565b6001546001600160a01b031681565b6036546201000090046001600160a01b031681565b60c881565b60006107b6826120d8565b90505b919050565b610741338460008086866000611671565b6714d1120d7b16000081565b6107ed33600080600086866000611671565b5050565b6107f9611508565b61084a576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6108538a6120f2565b61085c896120f2565b610865886120f2565b61086e876120f2565b610877866120f2565b610880856120f2565b610889846120f2565b610892836120f2565b61089b826120f2565b6036805462010000600160b01b031916620100006001600160a01b038d811691820292909217909255600080546001600160a01b03199081168d8416179091556001805482168c84161790556037805482168b84161790556038805482168a8416179055603980548216898416179055600280548216888416179055603c80548216878416179055603b80548216868416179055603a805490911691841691909117905560408051918252517f143219c9e69b09e07e095fcc889b43d8f46ca892bba65f08dc3a0050869a5678916020908290030190a1604080516001600160a01b038b16815290517f78f058b189175430c48dc02699e3a0031ea4ff781536dc2fab847de4babdd8829181900360200190a1604080516001600160a01b038a16815290517f5ee0cae2f063ed938bb55046f6a932fb6ae792bf43624806bb90abe68a50be9b9181900360200190a1604080516001600160a01b038916815290517f82966d27eea39b038ee0fa30cd16532bb24f6e65d31cb58fb227aa5766cdcc7f9181900360200190a1604080516001600160a01b038816815290517fcfb07d791fcafc032b35837b50eb84b74df518cf4cc287e8084f47630fa70fa09181900360200190a1604080516001600160a01b038716815290517fe67f36a6e961157d6eff83b91f3af5a62131ceb6f04954ef74f51c1c05e7f88d9181900360200190a1604080516001600160a01b038616815290517f8c537274438aa850a330284665d81a85dd38267d09e4050d416bfc94142db2649181900360200190a1604080516001600160a01b038516815290517f65f4cf077bc01e4742eb5ad98326f6e95b63548ea24b17f8d5e823111fe788009181900360200190a1604080516001600160a01b038416815290517f227eec0ec317af6ab1a9587ffa1c84332522eb4c583a908f89babc05f8f339bd9181900360200190a1604080516001600160a01b038316815290517f756ebc192164c295bba134b5aacd72cc7aff8098a670d1f0a5f6b3a0b4ce67079181900360200190a150505050505050505050565b6039546040805163b32beb5b60e01b815233600482015290516001600160a01b039092169163b32beb5b9160248082019260009290919082900301818387803b158015610be657600080fd5b505af1158015610763573d6000803e3d6000fd5b6002546001600160a01b031681565b603a546001600160a01b031681565b67120a871cc002000081565b6000805460408051632f5a97e560e11b8152905183926001600160a01b031691635eb52fca916004808301926020929190829003018186803b158015610c6957600080fd5b505afa158015610c7d573d6000803e3d6000fd5b505050506040513d6020811015610c9357600080fd5b505160015460408051632f5a97e560e11b815290519293506000926001600160a01b0390921691635eb52fca91600480820192602092909190829003018186803b158015610ce057600080fd5b505afa158015610cf4573d6000803e3d6000fd5b505050506040513d6020811015610d0a57600080fd5b50519050610d1e828263ffffffff6121a116565b9250505090565b3380610d2f611586565b6001600160a01b031614610d745760405162461bcd60e51b815260040180806020018281038252602981526020018061367e6029913960400191505060405180910390fd5b610d7d81612204565b50565b6000546001600160a01b031681565b6000610d9b6001612261565b90508015610db3576036805461ff0019166101001790555b610dbb61232d565b8015610d7d576036805461ff0019169055604080516001815290517f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989181900360200190a150565b610e0b613581565b50604080516060810182526036546001600160a01b03620100009091048116825260005481166020830152603b541691810191909152610e496135a1565b600260009054906101000a90046001600160a01b03166001600160a01b0316630fdb11cf6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610e9957600080fd5b505af1158015610ead573d6000803e3d6000fd5b505050506040513d6020811015610ec357600080fd5b5051808252600090610ed490612372565b9050610ee0878261238f565b8251610eec903361243b565b6040820186905280610f2d57610f0c83600001518460400151888a612517565b602083018190526040830151610f279163ffffffff6121a116565b60408301525b610f3a8260400151612662565b610f4782604001516120d8565b60608301819052610f5457fe5b610f6734836060015184600001516126aa565b60808301526060820151610f7c9034906126e9565b60a08301528015610f9957610f94826080015161271e565b610fcc565b610fa68260800151612765565b6000610fbf3460018560600151600187600001516127ac565b9050610fca81612837565b505b825160408051635d6b480f60e01b81523360048201526001602482015290516001600160a01b0390921691635d6b480f9160448082019260009290919082900301818387803b15801561101e57600080fd5b505af1158015611032573d6000803e3d6000fd5b50508451604080516372423c1760e01b815233600482015234602482015290516001600160a01b0390921693506372423c1792506044808201926020929091908290030181600087803b15801561108857600080fd5b505af115801561109c573d6000803e3d6000fd5b505050506040513d60208110156110b257600080fd5b50508251606083015160408051639976cf4560e01b81523360048201526024810192909252516001600160a01b0390921691639976cf45916044808201926020929091908290030181600087803b15801561110c57600080fd5b505af1158015611120573d6000803e3d6000fd5b505050506040513d602081101561113657600080fd5b50508251604080516382fe3eb960e01b815233600482015290516001600160a01b03909216916382fe3eb99160248082019260009290919082900301818387803b15801561118357600080fd5b505af1158015611197573d6000803e3d6000fd5b5050845160408051630c7940bd60e11b815233600482015290516001600160a01b0390921693506318f2817a92506024808201926020929091908290030181600087803b1580156111e757600080fd5b505af11580156111fb573d6000803e3d6000fd5b505050506040513d602081101561121157600080fd5b505160c0830152603c5460a0830151604080516346f7cf8760e01b815233600482015260248101929092526001600160a01b038881166044840152878116606484015290519216916346f7cf879160848082019260009290919082900301818387803b15801561128057600080fd5b505af1158015611294573d6000803e3d6000fd5b50508451604080516315d549f160e01b815233600482015290516001600160a01b0390921693506315d549f192506024808201926020929091908290030181600087803b1580156112e457600080fd5b505af11580156112f8573d6000803e3d6000fd5b505050506040513d602081101561130e57600080fd5b505160e08301819052604080519182525133917f59cfd0cd754bc5748b6770e94a4ffa5f678d885cb899dcfadc5734edb97c67ab919081900360200190a261135a83602001513461287e565b611373836020015184604001513389866040015161290e565b6020830151604084015160385461139e9291906001600160a01b0316670de0b6b3a76400008061290e565b336001600160a01b03166000805160206138858339815191528360600151348560c001516000604051808581526020018481526020018381526020018260028111156113e657fe5b60ff16815260200194505050505060405180910390a2602080830151604080519182525133927fa55c5f48fd29482ad55f4b59bf070cd1ac1a7132a31f7a136ebe8877ae37e1ff928290030190a250505050505050565b6000805460408051630a7b61df60e11b8152905183926001600160a01b0316916314f6c3be916004808301926020929190829003018186803b15801561148257600080fd5b505afa158015611496573d6000803e3d6000fd5b505050506040513d60208110156114ac57600080fd5b505160015460408051630a7b61df60e11b815290519293506000926001600160a01b03909216916314f6c3be91600480820192602092909190829003018186803b158015610ce057600080fd5b6003546001600160a01b031690565b6003546001600160a01b0316331490565b60405180604001604052806012815260200171426f72726f7765724f7065726174696f6e7360701b81525081565b603c546001600160a01b031681565b603b546001600160a01b031681565b610d7d3382611c81565b61157e3386868686868c611671565b505050505050565b6004546001600160a01b031690565b61159d6129eb565b61074183600080600086866000611671565b6115b7611508565b611608576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b03831690811790915561162e6114f9565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6611c37937e0800081565b611679613581565b50604080516060810182526036546001600160a01b03620100009091048116825260005481166020830152603b5416918101919091526116b76135e6565b600260009054906101000a90046001600160a01b03166001600160a01b0316630fdb11cf6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561170757600080fd5b505af115801561171b573d6000803e3d6000fd5b505050506040513d602081101561173157600080fd5b505180825260009061174290612372565b9050861561175d57611754848261238f565b61175d88612a34565b61176689612a73565b6117708989612ab9565b825161177c908b612b0b565b336001600160a01b038b1614806117b257506037546001600160a01b0316331480156117a85750600034115b80156117b2575087155b6117b857fe5b82600001516001600160a01b0316630b0765578b6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b15801561181457600080fd5b505af1158015611828573d6000803e3d6000fd5b50505050611836348a612bd0565b15156060840152602083015260408201889052868015611854575080155b1561188f5761186d836000015184604001518a87612517565b610120830181905260408301516118899163ffffffff6121a116565b60408301525b82600001516001600160a01b031663d66a25538b6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156118e957600080fd5b505afa1580156118fd573d6000803e3d6000fd5b505050506040513d602081101561191357600080fd5b505160808301528251604080516309019aaf60e31b81526001600160a01b038d811660048301529151919092169163480cd578916024808301926020929190829003018186803b15801561196657600080fd5b505afa15801561197a573d6000803e3d6000fd5b505050506040513d602081101561199057600080fd5b505160a08301819052608083015183516119ab9291906126aa565b8260c00181815250506119db8260a0015183608001518460200151856060015186604001518c8860000151612bef565b60e083015260a08201518911156119ee57fe5b6119fa818a8985612c22565b86158015611a085750600088115b15611a5b57611a36611a318360400151611a258560800151612c96565b9063ffffffff612cb016565b612662565b611a4882608001518360400151612cf2565b611a5b83604001518b8460400151612d48565b611a7983600001518b8460200151856060015186604001518c612e08565b610140840152610160830152825160408051630c7940bd60e11b81526001600160a01b038d81166004830152915191909216916318f2817a9160248083019260209291908290030181600087803b158015611ad357600080fd5b505af1158015611ae7573d6000803e3d6000fd5b505050506040513d6020811015611afd57600080fd5b505161018083015260a08201516080830151602084015160608501516040860151600094611b31949093909290918d613068565b603c546040805163015f109360e51b81526001600160a01b038f81166004830152602482018590528b811660448301528a811660648301529151939450911691632be212609160848082019260009290919082900301818387803b158015611b9857600080fd5b505af1158015611bac573d6000803e3d6000fd5b505050508a6001600160a01b0316600080516020613885833981519152846101400151856101600151866101800151600260405180858152602001848152602001838152602001826002811115611bff57fe5b60ff16815260200194505050505060405180910390a2610120830151604080519182525133917fa55c5f48fd29482ad55f4b59bf070cd1ac1a7132a31f7a136ebe8877ae37e1ff919081900360200190a2611c748460200151856040015133866020015187606001518e8e8a60400151613099565b5050505050505050505050565b603654600054603b546001600160a01b03620100009093048316929182169116611cab8385612b0b565b60025460408051630fdb11cf60e01b815290516000926001600160a01b031691630fdb11cf91600480830192602092919082900301818787803b158015611cf157600080fd5b505af1158015611d05573d6000803e3d6000fd5b505050506040513d6020811015611d1b57600080fd5b50519050611d2881613155565b836001600160a01b0316630b076557866040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b158015611d8057600080fd5b505af1158015611d94573d6000803e3d6000fd5b505050506000846001600160a01b031663480cd578876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611df057600080fd5b505afa158015611e04573d6000803e3d6000fd5b505050506040513d6020811015611e1a57600080fd5b50516040805163d66a255360e01b81526001600160a01b03898116600483015291519293506000929188169163d66a255391602480820192602092909190829003018186803b158015611e6c57600080fd5b505afa158015611e80573d6000803e3d6000fd5b505050506040513d6020811015611e9657600080fd5b50519050611ebc8489611eb784670de0b6b3a764000063ffffffff612cb016565b612d48565b6000611ecd836000846000886127ac565b9050611ed881612837565b866001600160a01b031663fe2ba848896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b158015611f3057600080fd5b505af1158015611f44573d6000803e3d6000fd5b50505050866001600160a01b031663cbd138ae896040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050600060405180830381600087803b158015611fa057600080fd5b505af1158015611fb4573d6000803e3d6000fd5b50505050876001600160a01b03166000805160206138858339815191526000806000600160405180858152602001848152602001838152602001826002811115611ffa57fe5b60ff16815260200194505050505060405180910390a261203386868b61202e86670de0b6b3a764000063ffffffff612cb016565b61319a565b60385461205590879087906001600160a01b0316670de0b6b3a764000061319a565b856001600160a01b03166364a197f389856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156120b557600080fd5b505af11580156120c9573d6000803e3d6000fd5b50505050505050505050505050565b60006107b682670de0b6b3a764000063ffffffff6121a116565b6001600160a01b03811661214d576040805162461bcd60e51b815260206004820152601e60248201527f4163636f756e742063616e6e6f74206265207a65726f20616464726573730000604482015290519081900360640190fd5b803b806107ed576040805162461bcd60e51b815260206004820181905260248201527f4163636f756e7420636f64652073697a652063616e6e6f74206265207a65726f604482015290519081900360640190fd5b6000828201838110156121fb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600480546001600160a01b0319908116909155600380546001600160a01b0384811693821684179092556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b603654600090610100900460ff16156122d0578160ff16600114801561228d575061228b3061326c565b155b6122c85760405162461bcd60e51b815260040180806020018281038252602e815260200180613747602e913960400191505060405180910390fd5b5060006107b9565b60365460ff8084169116106123165760405162461bcd60e51b815260040180806020018281038252602e815260200180613747602e913960400191505060405180910390fd5b506036805460ff191660ff831617905560016107b9565b600380546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350565b60008061237e83613272565b6714d1120d7b160000119392505050565b80156123e157670de0b6b3a76400008211156123dc5760405162461bcd60e51b81526004018080602001828103825260328152602001806137756032913960400191505060405180910390fd5b6107ed565b6611c37937e0800082108015906124005750670de0b6b3a76400008211155b6107ed5760405162461bcd60e51b8152600401808060200182810382526030815260200180613a0f6030913960400191505060405180910390fd5b6000826001600160a01b03166321e37801836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561249357600080fd5b505afa1580156124a7573d6000803e3d6000fd5b505050506040513d60208110156124bd57600080fd5b505190506001811415610741576040805162461bcd60e51b815260206004820152601c60248201527f426f72726f7765724f70733a2054726f76652069732061637469766500000000604482015290519081900360640190fd5b6000846001600160a01b0316635dba4c4a6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561255457600080fd5b505af1158015612568573d6000803e3d6000fd5b505050506000856001600160a01b031663631203b0856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156125b257600080fd5b505afa1580156125c6573d6000803e3d6000fd5b505050506040513d60208110156125dc57600080fd5b505190506125eb81858561329e565b603a54604080516340c10f1960e01b81526001600160a01b039283166004820152602481018490529051918716916340c10f199160448082019260009290919082900301818387803b15801561264057600080fd5b505af1158015612654573d6000803e3d6000fd5b509298975050505050505050565b68056bc75e2d63100000811015610d7d5760405162461bcd60e51b815260040180806020018281038252603a815260200180613969603a913960400191505060405180910390fd5b600082156126dd5760006126d4846126c8878663ffffffff61331316565b9063ffffffff61336c16565b91506126e29050565b506000195b9392505050565b600081156127155761270e826126c88568056bc75e2d6310000063ffffffff61331316565b90506121fe565b506000196121fe565b6714d1120d7b160000811015610d7d5760405162461bcd60e51b81526004018080602001828103825260378152602001806137106037913960400191505060405180910390fd5b67120a871cc0020000811015610d7d5760405162461bcd60e51b81526004018080602001828103825260498152602001806139206049913960600191505060405180910390fd5b6000806127b761143d565b905060006127c3610c24565b9050866127df576127da828963ffffffff612cb016565b6127ef565b6127ef828963ffffffff6121a116565b91508461280b57612806818763ffffffff612cb016565b61281b565b61281b818763ffffffff6121a116565b9050600061282a8383876126aa565b9998505050505050505050565b6714d1120d7b160000811015610d7d5760405162461bcd60e51b815260040180806020018281038252604981526020018061380e6049913960600191505060405180910390fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d80600081146128c9576040519150601f19603f3d011682016040523d82523d6000602084013e6128ce565b606091505b50509050806107415760405162461bcd60e51b815260040180806020018281038252602d815260200180613651602d913960400191505060405180910390fd5b846001600160a01b031663cfb9329a826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561295457600080fd5b505af1158015612968573d6000803e3d6000fd5b50505050836001600160a01b03166340c10f1984846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156129cc57600080fd5b505af11580156129e0573d6000803e3d6000fd5b505050505050505050565b6037546001600160a01b031633146107505760405162461bcd60e51b81526004018080602001828103825260298152602001806139e66029913960400191505060405180910390fd5b60008111610d7d5760405162461bcd60e51b8152600401808060200182810382526037815260200180613a3f6037913960400191505060405180910390fd5b341580612a7e575080155b610d7d5760405162461bcd60e51b81526004018080602001828103825260308152602001806136a76030913960400191505060405180910390fd5b34151580612ac657508115155b80612ad057508015155b6107ed5760405162461bcd60e51b81526004018080602001828103825260468152602001806137a76046913960600191505060405180910390fd5b6000826001600160a01b03166321e37801836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612b6357600080fd5b505afa158015612b77573d6000803e3d6000fd5b505050506040513d6020811015612b8d57600080fd5b50519050600181146107415760405162461bcd60e51b815260040180806020018281038252602e815260200180613857602e913960400191505060405180910390fd5b6000808315612be457508290506001612be8565b8291505b9250929050565b6000806000612c028a8a8a8a8a8a6133ae565b915091506000612c138383876126aa565b9b9a5050505050505050505050565b8315612c5b57612c3183613409565b8115612c5657612c448160e0015161271e565b612c568160e001518260c00151613446565b610763565b612c688160e00151612765565b612c858160200151826060015183604001518585600001516127ac565b610100820181905261076390612837565b60006107b682670de0b6b3a764000063ffffffff612cb016565b60006121fb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613485565b612d0a82670de0b6b3a764000063ffffffff612cb016565b8111156107ed5760405162461bcd60e51b81526004018080602001828103825260438152602001806139a36043913960600191505060405180910390fd5b80836001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612d9f57600080fd5b505afa158015612db3573d6000803e3d6000fd5b505050506040513d6020811015612dc957600080fd5b505110156107415760405162461bcd60e51b815260040180806020018281038252603d8152602001806138e3603d913960400191505060405180910390fd5b600080600085612ea357886001600160a01b031663d3d6f84389896040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612e7257600080fd5b505af1158015612e86573d6000803e3d6000fd5b505050506040513d6020811015612e9c57600080fd5b5051612f30565b886001600160a01b03166372423c1789896040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612f0357600080fd5b505af1158015612f17573d6000803e3d6000fd5b505050506040513d6020811015612f2d57600080fd5b50515b9050600084612fca57896001600160a01b03166312610e928a886040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612f9957600080fd5b505af1158015612fad573d6000803e3d6000fd5b505050506040513d6020811015612fc357600080fd5b5051613057565b896001600160a01b0316639976cf458a886040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561302a57600080fd5b505af115801561303e573d6000803e3d6000fd5b505050506040513d602081101561305457600080fd5b50515b919a91995090975050505050505050565b600080600061307b8989898989896133ae565b91509150600061308b83836126e9565b9a9950505050505050505050565b81156130b1576130ac888888868561290e565b6130bd565b6130bd8888888661319a565b83156130d2576130cd888661287e565b61314b565b876001600160a01b03166364a197f387876040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561313257600080fd5b505af1158015613146573d6000803e3d6000fd5b505050505b5050505050505050565b61315e81612372565b15610d7d5760405162461bcd60e51b81526004018080602001828103825260398152602001806136d76039913960400191505060405180910390fd5b836001600160a01b03166338d995a8826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156131e057600080fd5b505af11580156131f4573d6000803e3d6000fd5b50505050826001600160a01b0316639dc29fac83836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561325857600080fd5b505af115801561314b573d6000803e3d6000fd5b3b151590565b60008061327d61143d565b90506000613289610c24565b90506132968282866126aa565b949350505050565b60006132bc836126c886670de0b6b3a764000063ffffffff61331316565b905081811115610763576040805162461bcd60e51b815260206004820152601d60248201527f4665652065786365656465642070726f7669646564206d6178696d756d000000604482015290519081900360640190fd5b600082613322575060006121fe565b8282028284828161332f57fe5b04146121fb5760405162461bcd60e51b81526004018080602001828103825260218152602001806137ed6021913960400191505060405180910390fd5b60006121fb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061351c565b6000808787866133cd576133c88a8963ffffffff612cb016565b6133dd565b6133dd8a8963ffffffff6121a116565b9150846133f9576133f4898763ffffffff612cb016565b613057565b613057898763ffffffff6121a116565b8015610d7d5760405162461bcd60e51b815260040180806020018281038252603e8152602001806138a5603e913960400191505060405180910390fd5b808210156107ed5760405162461bcd60e51b815260040180806020018281038252603e815260200180613a76603e913960400191505060405180910390fd5b600081848411156135145760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156134d95781810151838201526020016134c1565b50505050905090810190601f1680156135065780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000818361356b5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156134d95781810151838201526020016134c1565b50600083858161357757fe5b0495945050505050565b604080516060810182526000808252602082018190529181019190915290565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b604051806101a00160405280600081526020016000815260200160008152602001600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509056fe426f72726f7765724f70733a2053656e64696e672045544820746f20416374697665506f6f6c206661696c65644f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206e6577206f776e6572426f72726f7765724f7065726174696f6e733a2043616e6e6f7420776974686472617720616e642061646420636f6c6c426f72726f7765724f70733a204f7065726174696f6e206e6f74207065726d697474656420647572696e67205265636f76657279204d6f6465426f72726f7765724f70733a204f7065726174696f6e206d757374206c656176652074726f7665207769746820494352203e3d20434352496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65644d6178206665652070657263656e74616765206d757374206c657373207468616e206f7220657175616c20746f2031303025426f72726f7765724f70733a205468657265206d75737420626520656974686572206120636f6c6c61746572616c206368616e6765206f7220612064656274206368616e6765536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77426f72726f7765724f70733a20416e206f7065726174696f6e207468617420776f756c6420726573756c7420696e20544352203c20434352206973206e6f74207065726d6974746564426f72726f7765724f70733a2054726f766520646f6573206e6f74206578697374206f7220697320636c6f736564c3770d654ed33aeea6bf11ac8ef05d02a6a04ed4686dd2f624d853bbec43cc8b426f72726f7765724f70733a20436f6c6c61746572616c207769746864726177616c206e6f74207065726d6974746564205265636f76657279204d6f6465426f72726f7765724f70733a2043616c6c657220646f65736e74206861766520656e6f756768204c55534420746f206d616b652072657061796d656e74426f72726f7765724f70733a20416e206f7065726174696f6e207468617420776f756c6420726573756c7420696e20494352203c204d4352206973206e6f74207065726d6974746564426f72726f7765724f70733a2054726f76652773206e65742064656274206d7573742062652067726561746572207468616e206d696e696d756d426f72726f7765724f70733a20416d6f756e7420726570616964206d757374206e6f74206265206c6172676572207468616e207468652054726f766527732064656274426f72726f7765724f70733a2043616c6c6572206973206e6f742053746162696c69747920506f6f6c4d6178206665652070657263656e74616765206d757374206265206265747765656e20302e352520616e642031303025426f72726f7765724f70733a204465627420696e637265617365207265717569726573206e6f6e2d7a65726f20646562744368616e6765426f72726f7765724f70733a2043616e6e6f7420646563726561736520796f75722054726f766527732049435220696e205265636f76657279204d6f6465a2646970667358221220a789934bdce548e88aed3684c786d46f2df254389f0df7d3087d79d91691a9e564736f6c634300060b0033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for
interesting conversations.