ETH Price: $2,635.15 (+1.30%)

Contract

0x634bcdB3C8e26fFe4764B6285FdBFD88b4f6370f
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Claim Remaining ...193682202024-03-05 9:58:59225 days ago1709632739IN
0x634bcdB3...8b4f6370f
0 ETH0.0061245159.77467914
Claim Remaining ...191576852024-02-04 21:43:11254 days ago1707082991IN
0x634bcdB3...8b4f6370f
0 ETH0.0014369314.02435812
Claim Remaining ...187547652023-12-10 8:58:11311 days ago1702198691IN
0x634bcdB3...8b4f6370f
0 ETH0.0024072723.49481423
Claim Remaining ...182162912023-09-26 0:10:47386 days ago1695687047IN
0x634bcdB3...8b4f6370f
0 ETH0.0011641311.36184124
Borrow LUSD Liqu...176722192023-07-11 18:41:23462 days ago1689100883IN
0x634bcdB3...8b4f6370f
0 ETH0.0156862432.61457906
Borrow LUSD Liqu...175368292023-06-22 18:05:59481 days ago1687457159IN
0x634bcdB3...8b4f6370f
0 ETH0.0078170216.25092874
Borrow LUSD Liqu...172444712023-05-12 13:37:11522 days ago1683898631IN
0x634bcdB3...8b4f6370f
0 ETH0.0288824859.69935586
Add Collateral L...172444492023-05-12 13:32:47522 days ago1683898367IN
0x634bcdB3...8b4f6370f
6.5 ETH0.0235088761.93374509
Add Collateral L...169246012023-03-28 8:18:23568 days ago1679991503IN
0x634bcdB3...8b4f6370f
9 ETH0.0108081924.35517027
Borrow LUSD Liqu...169245532023-03-28 8:08:23568 days ago1679990903IN
0x634bcdB3...8b4f6370f
0 ETH0.0132752724.94354128
Borrow LUSD Liqu...169245072023-03-28 7:59:11568 days ago1679990351IN
0x634bcdB3...8b4f6370f
0 ETH0.0117677324.12638305
Borrow LUSD Liqu...168129622023-03-12 15:53:47583 days ago1678636427IN
0x634bcdB3...8b4f6370f
0 ETH0.0101444321.17187317
Borrow LUSD Liqu...167412762023-03-02 13:48:59593 days ago1677764939IN
0x634bcdB3...8b4f6370f
0 ETH0.0118880224.72031584
Borrow LUSD Liqu...167410582023-03-02 13:04:35593 days ago1677762275IN
0x634bcdB3...8b4f6370f
0 ETH0.0138769924.55853613
Borrow LUSD Liqu...165859252023-02-08 18:47:11615 days ago1675882031IN
0x634bcdB3...8b4f6370f
0 ETH0.0161057133.59746439
Open Credit Line...161402522022-12-08 13:21:23677 days ago1670505683IN
0x634bcdB3...8b4f6370f
42 ETH0.024759919.15787179
Add Collateral L...159892132022-11-17 10:41:35699 days ago1668681695IN
0x634bcdB3...8b4f6370f
1 ETH0.0059620113.49432911
Close Credit Lin...159844522022-11-16 18:45:11699 days ago1668624311IN
0x634bcdB3...8b4f6370f
0 ETH0.0090095820.5
Withdraw Collate...159841762022-11-16 17:49:11699 days ago1668620951IN
0x634bcdB3...8b4f6370f
0 ETH0.0096796422.1
Repay LUSD Liqui...159841642022-11-16 17:46:47699 days ago1668620807IN
0x634bcdB3...8b4f6370f
0 ETH0.0100943922.15
Repay LUSD Liqui...159841412022-11-16 17:41:59699 days ago1668620519IN
0x634bcdB3...8b4f6370f
0 ETH0.0090618520.8
Withdraw Collate...159840752022-11-16 17:28:47699 days ago1668619727IN
0x634bcdB3...8b4f6370f
0 ETH0.0092478521.25
Repay LUSD Liqui...159826842022-11-16 12:47:59699 days ago1668602879IN
0x634bcdB3...8b4f6370f
0 ETH0.00621613.08
Withdraw Collate...159818942022-11-16 10:08:59700 days ago1668593339IN
0x634bcdB3...8b4f6370f
0 ETH0.0061280413.91305742
Borrow LUSD Liqu...157172562022-10-10 10:58:35737 days ago1665399515IN
0x634bcdB3...8b4f6370f
0 ETH0.0182993338.44042446
View all transactions

Latest 13 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
172444492023-05-12 13:32:47522 days ago1683898367
0x634bcdB3...8b4f6370f
6.5 ETH
169246012023-03-28 8:18:23568 days ago1679991503
0x634bcdB3...8b4f6370f
9 ETH
161402522022-12-08 13:21:23677 days ago1670505683
0x634bcdB3...8b4f6370f
42 ETH
159892132022-11-17 10:41:35699 days ago1668681695
0x634bcdB3...8b4f6370f
1 ETH
156741092022-10-04 10:14:47743 days ago1664878487
0x634bcdB3...8b4f6370f
4.95 ETH
152008912022-07-23 19:51:07815 days ago1658605867
0x634bcdB3...8b4f6370f
0.6 ETH
152008192022-07-23 19:38:10815 days ago1658605090
0x634bcdB3...8b4f6370f
2.45 ETH
150938202022-07-07 6:32:15832 days ago1657175535
0x634bcdB3...8b4f6370f
2.7 ETH
150649712022-07-02 19:23:37836 days ago1656789817
0x634bcdB3...8b4f6370f
17 ETH
149560612022-06-13 12:47:25855 days ago1655124445
0x634bcdB3...8b4f6370f
29 ETH
149379422022-06-10 10:27:38859 days ago1654856858
0x634bcdB3...8b4f6370f
4 ETH
148607562022-05-28 14:19:14871 days ago1653747554
0x634bcdB3...8b4f6370f
3.9 ETH
148606282022-05-28 13:49:53871 days ago1653745793
0x634bcdB3...8b4f6370f
4 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Stargate

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU LGPLv3 license
File 1 of 17 : Stargate.sol
// SPDX-License-Identifier: LGPL-3.0
pragma solidity =0.8.10;

import "./Registry.sol";
import "./dapphub/DSProxyFactory.sol";
import "./dapphub/DSProxy.sol";
import "./Config.sol";
import "./CentralLogger.sol";
import "./CommunityAcknowledgement.sol";
import "./LiquityMath.sol";
import "./SqrtMath.sol";
import "./interfaces/ITroveManager.sol";
import "./interfaces/IHintHelpers.sol";
import "./interfaces/ISortedTroves.sol";
import "./interfaces/ICollSurplusPool.sol";


/// @title Stargate contract serves as a gateway and a gatekeeper into the APUS protocol ecosystem
/// @notice The main motivation of Stargate is to give user understandable transaction to sign (i.e. no bytecode giberish) 
/// and to chain common sequence of transactions thus saving gas.
/// @dev It encodes all arguments and calls given user's Smart Account proxy with any additional arguments
contract Stargate is LiquityMath, SqrtMath {

	/* solhint-disable var-name-mixedcase */

	/// @notice Registry's contracts IDs
	bytes32 private constant EXECUTOR_ID = keccak256("Executor");
	bytes32 private constant CONFIG_ID = keccak256("Config");
	bytes32 private constant AUTHORITY_ID = keccak256("Authority");
	bytes32 private constant COMMUNITY_ACKNOWLEDGEMENT_ID = keccak256("CommunityAcknowledgement");
	bytes32 private constant CENTRAL_LOGGER_ID = keccak256("CentralLogger");

	/// @notice APUS registry address
	address public immutable registry;

	// MakerDAO's deployed contracts - Proxy Factory
	// see https://changelog.makerdao.com/
	DSProxyFactory public immutable ProxyFactory;

	// L1 Liquity deployed contracts addresses
	// see https://docs.liquity.org/documentation/resources#contract-addresses
	ITroveManager public immutable TroveManager;
	IHintHelpers public immutable HintHelpers;
	ISortedTroves public immutable SortedTroves;
	ICollSurplusPool public immutable CollSurplusPool;


	/// @notice Event raised on Stargate when a new Smart Account is created. 
	/// Corresponding event is also raised on the Central Logger
	event SmartAccountCreated(
		address indexed owner,
		address indexed smartAccountAddress
	);


	/// @notice Modifier will fail if message sender is not the proxy owner
	/// @param _proxy Proxy address that must be owned
	modifier onlyProxyOwner(address payable _proxy) {
		require(DSProxy(_proxy).owner() == msg.sender, "Sender has to be proxy owner");
		_;
	}

	/* solhint-disable-next-line func-visibility */
	constructor(
		address _registry,
		address _troveManager,
		address _hintHelpers,
		address _sortedTroves,
		address _collSurplusPool,
		address _proxyFactory
	) {
		registry = _registry;
		TroveManager = ITroveManager(_troveManager);
		HintHelpers = IHintHelpers(_hintHelpers);
		SortedTroves = ISortedTroves(_sortedTroves);
		CollSurplusPool = ICollSurplusPool(_collSurplusPool);
		ProxyFactory = DSProxyFactory(_proxyFactory);
	}

	/// @notice Execute proxy call with encoded transaction data and eth value
	/// @dev Proxy delegates call to executor address which is obtained from registry contract
	/// @param _proxy Proxy address to execute encoded transaction
	/// @param _value Value of eth to transfer with function call
	/// @param _data Transaction data to execute
	function _execute(address payable _proxy, uint256 _value, bytes memory _data) internal onlyProxyOwner(_proxy) {
		DSProxy(_proxy).execute{ value: _value }(Registry(registry).getAddress(EXECUTOR_ID), _data);
	}

	/// @notice Execute proxy call with encoded transaction data and eth value by anyone
	/** 
	 * @dev Proxy delegates call to executor address which is obtained from registry contract
	 *
	 * This is the DANGEROUS version as it enables the proxy call to be performed by anyone!
	 *
	 * However suitable for cases when user wants to provide ETH from other (proxy non-owning) accounts.
	 */
	/// @param _proxy Proxy address to execute encoded transaction
	/// @param _value Value of eth to transfer with function call
	/// @param _data Transaction data to execute
	function _executeByAnyone(address payable _proxy, uint256 _value, bytes memory _data) internal {
		DSProxy(_proxy).execute{ value: _value }(Registry(registry).getAddress(EXECUTOR_ID), _data);
	}

	// Stargate MUST NOT be able to receive ETH from sender to itself
	// in 0.8.x function() is split to receive() and fallback(); if both are undefined -> tx reverts

	// ------------------------------------------ User functions ------------------------------------------


	/// @notice Creates the Smart Account directly. Its new address is emitted to the event.
	/// It is cheaper to open Smart Account while opening Credit Line wihin 1 transaction.
	function openSmartAccount() external {
		_openSmartAccount();
	}

	/// @notice Builds the new MakerDAO's proxy aka Smart Account with enabled calls from this Stargate
	function _openSmartAccount() internal returns (address payable) {
	
		// Deploy a new MakerDAO's proxy onto blockchain
		DSProxy smartAccount = ProxyFactory.build();

		// Enable Stargate's user functions to call the Smart Account	
		DSAuthority stargateAuthority = DSAuthority(Registry(registry).getAddress(AUTHORITY_ID));
		smartAccount.setAuthority(stargateAuthority); 

		// Set owner of MakerDAO's proxy aka Smart Account to be the user
		smartAccount.setOwner(msg.sender);

		// Emit centraly at this contract and the Central Logger
		emit SmartAccountCreated(msg.sender, address(smartAccount));
		CentralLogger logger = CentralLogger(Registry(registry).getAddress(CENTRAL_LOGGER_ID));
		logger.log(
			address(this), msg.sender, "openSmartAccount", abi.encode(smartAccount)
		);
				
		return payable(smartAccount);
	}

	/// @notice Get the gasless information on Credit Line (Liquity) status of the given Smart Account
	/// @param _smartAccount Smart Account address.
	/// @return status Status of the Credit Line within Liquity protocol, where:
	/// 0..nonExistent,
	/// 1..active,
	/// 2..closedByOwner,
	/// 3..closedByLiquidation,
	/// 4..closedByRedemption
	/// @return collateral ETH collateral.
	/// @return debtToRepay Total amount of LUSD needed to close the Credit Line (exluding the 200 LUSD liquidation reserve).
	/// @return debtComposite Composite debt including the liquidation reserve. Valid for LTV (CR) calculations.   
	function getCreditLineStatusLiquity(address payable _smartAccount) external view returns (
		uint8 status,
		uint256 collateral,
		uint256 debtToRepay, 
		uint256 debtComposite
	) {
		(debtComposite, collateral, , status, ) = TroveManager.Troves(_smartAccount);	
		debtToRepay = debtComposite > LIQUITY_LUSD_GAS_COMPENSATION ? debtComposite - LIQUITY_LUSD_GAS_COMPENSATION : 0;
	}

	/// @notice Calculates Liquity sorting hints based on the provided NICR
	function getLiquityHints(uint256 NICR) internal view returns (
		address upperHint,
		address lowerHint
	) {
		// Get an approximate address hint from the deployed HintHelper contract.
		uint256 numTroves = SortedTroves.getSize();
		uint256 numTrials = sqrt(numTroves) * 15;
		(address approxHint, , ) = HintHelpers.getApproxHint(NICR, numTrials, 0x41505553);

		// Use the approximate hint to get the exact upper and lower hints from the deployed SortedTroves contract
		(upperHint, lowerHint) = SortedTroves.findInsertPosition(NICR, approxHint, approxHint);
	}

	/// @notice Calculates LUSD expected debt to repay. 
	/// Includes _LUSDRequested, Adoption Contribution, Liquity protocol fee.
	/// Adoption Contribution reflects the Adoption Contribution Rate and Recognised Community Contributor Acknowledgement Rate if applicable.
	function getLiquityExpectedDebtToRepay(uint256 _LUSDRequested) internal view returns (uint256 expectedDebtToRepay) {
		uint16 applicableAcr;
		uint256 expectedLiquityProtocolRate;

		(applicableAcr, expectedLiquityProtocolRate) = getLiquityRates();

		uint256 neededLUSDAmount = calcNeededLiquityLUSDAmount(_LUSDRequested, expectedLiquityProtocolRate, applicableAcr);

		uint256 expectedLiquityProtocolFee = TroveManager.getBorrowingFeeWithDecay(neededLUSDAmount);

		expectedDebtToRepay = neededLUSDAmount + expectedLiquityProtocolFee;
	}

	/// @notice Calculates the rates related to Liquity for the msg.sender
	/// @return applicableAcr Adoption Contribution Rate with applied Recognised Community Contributor Acknowledgement Rate of msg.sender if applicable.
	/// @return expectedLiquityProtocolRate Current rate of the Liquity protocol
	function getLiquityRates() internal view returns (uint16 applicableAcr, uint256 expectedLiquityProtocolRate) {
		// Get and apply Recognised Community Contributor Acknowledgement Rate
		CommunityAcknowledgement ca = CommunityAcknowledgement(Registry(registry).getAddress(COMMUNITY_ACKNOWLEDGEMENT_ID));
		uint16 rccar = ca.getAcknowledgementRate(keccak256(abi.encodePacked(msg.sender)));

		Config config = Config(Registry(registry).getAddress(CONFIG_ID));

		applicableAcr = applyRccarOnAcr(rccar, config.adoptionContributionRate());

		expectedLiquityProtocolRate = TroveManager.getBorrowingRateWithDecay();
	}

	/// @notice Calculates the current rate for the msg.sender as related to Liquity and Adoption Contribution incl. RCCAR
	function userAdoptionRate() external view returns (uint256) {
		uint16 applicableAcr;
		uint256 expectedLiquityProtocolRate;

		(applicableAcr, expectedLiquityProtocolRate) = getLiquityRates();

		// Normalise applicable ACR 1e4 -> 1e18
        uint256 r = DECIMAL_PRECISION / ACR_DECIMAL_PRECISION * applicableAcr;

        // Apply Liquity protocol rate when applicable ACR is lower
        return r < expectedLiquityProtocolRate ? expectedLiquityProtocolRate : r;
	}

	/// @notice Makes a gasless calculation to get the data for the Credit Line's initial setup on Liquity protocol
    /// @param _LUSDRequested Requested LUSD amount to be taken by borrower. In e18 (1 LUSD = 1e18).
	///	  		Adoption Contribution including protocol's fees is applied in the form of additional debt.
    /// @param _collateralAmount Amount of ETH to be deposited into the Credit Line. In wei (1 ETH = 1e18).
	/// @return expectedDebtToRepay Total amount of LUSD needed to close the Credit Line (exluding the 200 LUSD liquidation reserve).
	/// @return liquidationReserve Liquidation gas reserve required by the Liquity protocol.
	/// @return expectedCompositeDebtLiquity Total debt of the new Credit Line including the liquidation reserve. Valid for LTV (CR) calculations.
	/// @return NICR Nominal Individual Collateral Ratio for this calculation as defined and used by Liquity protocol.
	/// @return upperHint Calculated hint for gas optimalization of the Liquity protocol when opening new Credit Line with openCreditLineLiquity.
	/// @return lowerHint Calculated hint for gas optimalization of the Liquity protocol when opening new Credit Line with openCreditLineLiquity.
    function calculateInitialLiquityParameters(uint256 _LUSDRequested, uint256 _collateralAmount) public view returns (
		uint256 expectedDebtToRepay,
		uint256 liquidationReserve,
		uint256 expectedCompositeDebtLiquity,
        uint256 NICR,
		address upperHint,
		address lowerHint
    ) {
		liquidationReserve = LIQUITY_LUSD_GAS_COMPENSATION;

		expectedDebtToRepay = getLiquityExpectedDebtToRepay(_LUSDRequested);

		expectedCompositeDebtLiquity = expectedDebtToRepay + LIQUITY_LUSD_GAS_COMPENSATION;

		// Get the nominal NICR of the new Liquity's trove
		NICR = _collateralAmount * 1e20 / expectedCompositeDebtLiquity;

		(upperHint, lowerHint) = getLiquityHints(NICR);
    }

	/// @notice Makes a gasless calculation to get the data for the Credit Line's adjustement on Liquity protocol
	/// @param _isDebtIncrease Indication whether _LUSDRequestedChange increases debt (true), decreases debt(false) or does not impact debt (false).
	/// @param _LUSDRequestedChange Amount of LUSD to be returned or further borrowed. The increase or decrease is indicated by _isDebtIncrease.
	///			Adoption Contribution including protocol's fees is applied in the form of additional debt in case of requested debt increase.
	/// @param _isCollateralIncrease Indication whether _LUSDRequestedChange increases debt (true), decreases debt(false) or does not impact debt (false).
	/// @param _collateralChange Amount of ETH collateral to be withdrawn or added. The increase or decrease is indicated by _isCollateralIncrease.
	/// @return newCollateral Calculated future collateral.
	/// @return expectedDebtToRepay Total future amount of LUSD needed to close the Credit Line (exluding the 200 LUSD liquidation reserve).
	/// @return liquidationReserve Liquidation gas reserve required by the Liquity protocol.
	/// @return expectedCompositeDebtLiquity Total future debt of the new Credit Line including the liquidation reserve. Valid for LTV (CR) calculations.
	/// @return NICR Nominal Individual Collateral Ratio for this calculation as defined and used by Liquity protocol.
	/// @return upperHint Calculated hint for gas optimalization of the Liquity protocol when opening new Credit Line with openCreditLineLiquity.
	/// @return lowerHint Calculated hint for gas optimalization of the Liquity protocol when opening new Credit Line with openCreditLineLiquity.
	/// @dev bools and uints are used to avoid typecasting and overflow issues and to explicitely signal the direction
	function calculateChangedLiquityParameters(
		bool _isDebtIncrease,
		uint256 _LUSDRequestedChange,
		bool _isCollateralIncrease,
		uint256 _collateralChange,
		address payable _smartAccount
	)  public view returns (
		uint256 newCollateral,
		uint256 expectedDebtToRepay,
		uint256 liquidationReserve,
		uint256 expectedCompositeDebtLiquity,
        uint256 NICR,
		address upperHint,
		address lowerHint
    ) {
		liquidationReserve = LIQUITY_LUSD_GAS_COMPENSATION;

		// Get the current LUSD debt and ETH collateral
		(uint256 currentCompositeDebt, uint256 currentCollateral, , ) = TroveManager.getEntireDebtAndColl(_smartAccount);

		uint256 currentDebtToRepay = currentCompositeDebt - LIQUITY_LUSD_GAS_COMPENSATION;

		if (_isCollateralIncrease) {
			newCollateral = currentCollateral + _collateralChange;
		} else {
			newCollateral = currentCollateral - _collateralChange;
		}

		if (_isDebtIncrease) {
			uint256 additionalDebtToRepay = getLiquityExpectedDebtToRepay(_LUSDRequestedChange);
			expectedDebtToRepay = currentDebtToRepay + additionalDebtToRepay;
		} else {
			expectedDebtToRepay = currentDebtToRepay - _LUSDRequestedChange;
		}

		expectedCompositeDebtLiquity = expectedDebtToRepay + LIQUITY_LUSD_GAS_COMPENSATION;

		// Get the nominal NICR of the new Liquity's trove
		NICR = newCollateral * 1e20 / expectedCompositeDebtLiquity;

		(upperHint, lowerHint) = getLiquityHints(NICR);

	}

	/// @notice Opens a new Credit Line using Liquity protocol by depositing ETH collateral and borrowing LUSD.
	/// Creates the new Smart Account (MakerDAO's proxy) if requested.
	/// Use calculateInitialLiquityParameters for gasless calculation of proper Hints for _LUSDRequested.
	/// @param _LUSDRequested Amount of LUSD caller wants to borrow and withdraw. In e18 (1 LUSD = 1e18).
	/// @param _LUSDTo Address that will receive the generated LUSD. Can be different to save gas on transfer.
	/// @param _upperHint For gas optimalisation when using Liquity protocol. Use calculateInitialLiquityParameters for gasless calculation of proper Hints for _LUSDRequested.
	/// @param _lowerHint For gas optimalisation when using Liquity protocol. Use calculateInitialLiquityParameters for gasless calculation of proper Hints for _LUSDRequested.
	/// @param _smartAccount Smart Account address. When 0x0000...00 sender requests to open a new Smart Account.
	/// @dev Hints explained: https://github.com/liquity/dev#supplying-hints-to-trove-operations
	/// @dev Value is amount of ETH to deposit into Liquity protocol.
	function openCreditLineLiquity(uint256 _LUSDRequested, address _LUSDTo, address _upperHint, address _lowerHint, address payable _smartAccount) external payable {

		// By submitting 0x00..0 as the smartAccount address the caller wants to open a new Smart Account during this 1 transaction and thus saving gas.
		_smartAccount = (_smartAccount == address(0)) ? _openSmartAccount() : _smartAccount;

		_execute(_smartAccount, msg.value, abi.encodeWithSignature(
			"openCreditLineLiquity(uint256,address,address,address,address)",
			_LUSDRequested, _LUSDTo, _upperHint, _lowerHint, msg.sender
		));

	}

	/// @notice Allows a borrower to repay all LUSD debt, withdraw all their ETH collateral, and close their Credit Line on Liquity protocol.
	/// @param _LUSDFrom Address where the LUSD is being pulled from to repay debt.
	/// @param _collateralTo Address that will receive the withdrawn ETH.
	/// @param _smartAccount Smart Account address
	function closeCreditLineLiquity(address _LUSDFrom, address payable _collateralTo, address payable _smartAccount) public {

		_execute(_smartAccount, 0, 
			abi.encodeWithSignature(
				"closeCreditLineLiquity(address,address,address)",
				_LUSDFrom,
				_collateralTo, 
				msg.sender
		));

	}

	/// @notice Allows a borrower to repay all LUSD debt, withdraw all their ETH collateral, and close their Credit Line on Liquity protocol using EIP2612 Permit.
	/// @param _LUSDFrom Address where the LUSD is being pulled from to repay debt.
	/// @param _collateralTo Address that will receive the withdrawn ETH.
	/// @param v EIP2612 secp256k1 permit signature part
	/// @param r EIP2612 secp256k1 permit signature part
	/// @param s EIP2612 secp256k1 permit signature part
	/// @param _smartAccount Smart Account address
	function closeCreditLineLiquityWithPermit(address _LUSDFrom, address payable _collateralTo, uint8 v, bytes32 r, bytes32 s, address payable _smartAccount) external {

		_execute(_smartAccount, 0, abi.encodeWithSignature(
			"closeCreditLineLiquityWithPermit(address,address,uint8,bytes32,bytes32,address)",
			_LUSDFrom, _collateralTo, v, r, s, msg.sender
		));

	}

	/// @notice Enables a borrower to simultaneously change both their collateral and debt.
	/// Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// @param _isDebtIncrease Indication whether _LUSDRequestedChange increases debt (true), decreases debt(false) or does not impact debt (false).
	/// @param _LUSDRequestedChange Amount of LUSD to be returned or further borrowed.
	///			The increase or decrease is indicated by _isDebtIncrease.
	///			Adoption Contribution and protocol's fees are applied in the form of additional debt in case of requested debt increase.
	/// @param _LUSDAddress Address where the LUSD is being pulled from in case of to repaying debt.
	/// Or address that will receive the generated LUSD in case of increasing debt.
	/// Approval of LUSD transfers for given Smart Account is required in case of repaying debt.
	/// @param _collWithdrawal Amount of ETH collateral to withdraw. MUST be 0 if ETH is provided to increase collateral.
	/// @param _collateralTo Address that will receive the withdrawn collateral ETH.
	/// @param _upperHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// @param _lowerHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// @param _smartAccount Smart Account address
	/// @dev Hints explained: https://github.com/liquity/dev#supplying-hints-to-trove-operations
	/// @dev Hints should reflect calculated neededLUSDAmount instead of _LUSDRequestedChange
	/// @dev Value is amount of ETH to deposit into Liquity protocol
	function adjustCreditLineLiquity(
		bool _isDebtIncrease,
		uint256 _LUSDRequestedChange,
		address _LUSDAddress,
		uint256 _collWithdrawal,
		address payable _collateralTo,
		address _upperHint, address _lowerHint,
		address payable _smartAccount) external payable {

		_execute(_smartAccount, msg.value, abi.encodeWithSignature(
			"adjustCreditLineLiquity(bool,uint256,address,uint256,address,address,address,address)",
			_isDebtIncrease, _LUSDRequestedChange, _LUSDAddress, _collWithdrawal, _collateralTo, _upperHint, _lowerHint, msg.sender
		));

	}

	/// @notice Enables a borrower to simultaneously change both their collateral and decrease debt providing LUSD from ANY ADDRESS using EIP2612 Permit. 
	/// Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// It is useful only when the debt decrease is requested while working with collateral.
	/// In all other cases [adjustCreditLineLiquity()] MUST be used. It is cheaper on gas.
	/// @param _LUSDRequestedChange Amount of LUSD to be returned.
	/// @param _LUSDFrom Address where the LUSD is being pulled from. Can be ANY ADDRESS with enough LUSD.
	/// Approval of LUSD transfers for given Smart Account is ensured by the offchain signature from that address.
	/// @param _collWithdrawal Amount of ETH collateral to withdraw. MUST be 0 if ETH is provided to increase collateral.
	/// @param _collateralTo Address that will receive the withdrawn collateral ETH.
	/// @param _upperHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// @param _lowerHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// @param v EIP2612 secp256k1 permit signature part
	/// @param r EIP2612 secp256k1 permit signature part
	/// @param s EIP2612 secp256k1 permit signature part
	/// @param _smartAccount Smart Account address
	/// @dev Hints explained: https://github.com/liquity/dev#supplying-hints-to-trove-operations
	/// @dev Value is amount of ETH to deposit into Liquity protocol
	function adjustCreditLineLiquityWithPermit(
		uint256 _LUSDRequestedChange,
		address _LUSDFrom,
		uint256 _collWithdrawal,
		address payable _collateralTo,
		address _upperHint, address _lowerHint,
		uint8 v, bytes32 r, bytes32 s,
		address payable _smartAccount) external payable {

		_execute(_smartAccount, msg.value, abi.encodeWithSignature(
			"adjustCreditLineLiquityWithPermit(uint256,address,uint256,address,address,address,uint8,bytes32,bytes32,address)",
			_LUSDRequestedChange, _LUSDFrom, _collWithdrawal, _collateralTo, _upperHint, _lowerHint, v, r, s, msg.sender
		));

	}

	/// @notice Gasless check if there is anything to be claimed after the forced closure of the Liquity Credit Line
	function checkClaimableCollateralLiquity(address _smartAccount) external view returns (uint256) {
		return CollSurplusPool.getCollateral(_smartAccount);
	}

	/// @notice Claims remaining collateral from the user's closed Credit Line (Liquity protocol) due to a redemption or a liquidation.
	/// @param _collateralTo Address that will receive the claimed collateral ETH.
	/// @param _smartAccount Smart Account address
	function claimRemainingCollateralLiquity(address payable _collateralTo, address payable _smartAccount) external {
		_execute(_smartAccount, 0, abi.encodeWithSignature(
			"claimRemainingCollateralLiquity(address,address)",
			_collateralTo,
			msg.sender
		));
	}


	/// @notice Allows ANY ADDRESS (calling and paying) to add ETH collateral to borrower's Credit Line (Liquity protocol) and thus increase CR (decrease LTV ratio).
	/// @param _upperHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints.
	/// @param _lowerHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints.
	/// @param _smartAccount Smart Account address
	/// @dev Hints explained: https://github.com/liquity/dev#supplying-hints-to-trove-operations
	function addCollateralLiquity(address _upperHint, address _lowerHint, address payable _smartAccount) external payable {

		// Must be executable by anyone in order to be able to provide ETH by addresses, which do not own smart account proxy
		_executeByAnyone(_smartAccount, msg.value, abi.encodeWithSignature(
			"addCollateralLiquity(address,address,address)",
			_upperHint, _lowerHint, msg.sender
		));
	}

	/// @notice Withdraws amount of ETH collateral from the Credit Line and transfer to _collateralTo address.
	/// @param _collWithdrawal Amount of ETH collateral to withdraw
	/// @param _collateralTo Address that will receive the withdrawn collateral ETH
	/// @param _upperHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints.
	/// @param _lowerHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints.
	/// @param _smartAccount Smart Account address
	/// @dev Hints explained: https://github.com/liquity/dev#supplying-hints-to-trove-operations
	function withdrawCollateralLiquity(uint256 _collWithdrawal, address payable _collateralTo, address _upperHint, address _lowerHint, address payable _smartAccount) external {

		_execute(_smartAccount, 0, abi.encodeWithSignature(
			"withdrawCollateralLiquity(uint256,address,address,address,address)",
			_collWithdrawal, _collateralTo, _upperHint, _lowerHint, msg.sender
		));

	}

	/// @notice Issues amount of LUSD from the liquity's protocol to the provided address.
	/// This increases the debt on the Credit Line, decreases CR (increases LTV).
	/// @param _LUSDRequestedChange Amount of LUSD to further borrow.
	/// @param _LUSDTo Address that will receive the generated LUSD. When 0 msg.sender is used.
	/// @param _upperHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// @param _lowerHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// @param _smartAccount Smart Account address
	/// @dev Hints explained: https://github.com/liquity/dev#supplying-hints-to-trove-operations
	/// @dev Hints should reflect calculated new debt instead of _LUSDRequestedChange
	/// @dev This is facade to adjustCreditLineLiquity
	function borrowLUSDLiquity(uint256 _LUSDRequestedChange, address _LUSDTo, address _upperHint, address _lowerHint, address payable _smartAccount) external {

		_execute(_smartAccount, 0, abi.encodeWithSignature(
			"adjustCreditLineLiquity(bool,uint256,address,uint256,address,address,address,address)",
			true, _LUSDRequestedChange, _LUSDTo, 0, msg.sender, _upperHint, _lowerHint, msg.sender
//			_isDebtIncrease, _LUSDRequestedChange, _LUSDAddress, _collWithdrawal, _collateralTo, _upperHint, _lowerHint, msg.sender
		));

	}

	/// @notice Enables credit line owner to partially repay the debt from ANY ADDRESS by the given amount of LUSD.
	/// Approval of LUSD transfers for given Smart Account is required.
	/// Cannot repay below 2000 LUSD composite debt. Use closeCreditLineLiquity to repay whole debt instead.
	/// @param _LUSDRequestedChange Amount of LUSD to be repaid in e18 (1 LUSD = 1e18). Repaying is subject to leaving 2000 LUSD min. debt in the Liquity protocol.
	/// @param _LUSDFrom Address where the LUSD is being pulled from to repay debt.
	/// @param _upperHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// @param _lowerHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// @param _smartAccount Smart Account address.
	/// @dev Hints explained: https://github.com/liquity/dev#supplying-hints-to-trove-operations
	function repayLUSDLiquity(uint256 _LUSDRequestedChange, address _LUSDFrom, address _upperHint, address _lowerHint, address payable _smartAccount) external {

		_execute(_smartAccount, 0, abi.encodeWithSignature(
			"repayLUSDLiquity(uint256,address,address,address,address)",
			_LUSDRequestedChange, _LUSDFrom, _upperHint, _lowerHint, msg.sender
		));

	}

	/// @notice Enables credit line owner to partially repay the debt from ANY ADDRESS by the given amount of LUSD using EIP2612 Permit.
	/// Approval of LUSD transfers for given Smart Account is ensured by the offchain signature.
	/// Cannot repay below 2000 LUSD composite debt. Use closeCreditLineLiquity to repay whole debt instead.
	/// @param _LUSDRequestedChange Amount of LUSD to be repaid in e18 (1 LUSD = 1e18). Repaying is subject to leaving 2000 LUSD min. debt in the Liquity protocol.
	/// @param _LUSDFrom Address where the LUSD is being pulled from to repay debt.
	/// @param _upperHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// @param _lowerHint For gas optimalisation when using Liquity protocol. Use calculateChangedLiquityParameters for gasless calculation of proper Hints for _LUSDRequestedChange.
	/// @param v EIP2612 secp256k1 permit signature part
	/// @param r EIP2612 secp256k1 permit signature part
	/// @param s EIP2612 secp256k1 permit signature part
	/// @param _smartAccount Smart Account address.
	/// @dev Hints explained: https://github.com/liquity/dev#supplying-hints-to-trove-operations
	function repayLUSDLiquityWithPermit(uint256 _LUSDRequestedChange, address _LUSDFrom, address _upperHint, address _lowerHint, uint8 v, bytes32 r, bytes32 s, address payable _smartAccount) external {

		_execute(_smartAccount, 0, abi.encodeWithSignature(
			"repayLUSDLiquityWithPermit(uint256,address,address,address,uint8,bytes32,bytes32,address)",
			_LUSDRequestedChange, _LUSDFrom, _upperHint, _lowerHint, v, r, s, msg.sender
		));

	}

}

File 2 of 17 : BaseMath.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

contract BaseMath {

    /// @notice Constant for the fractional arithmetics. Similar to 1 ETH = 1e18 wei.
    uint256 constant internal DECIMAL_PRECISION = 1e18;

    /// @notice Constant for the fractional arithmetics with ACR.
    uint256 constant internal ACR_DECIMAL_PRECISION = 1e4;

}

File 3 of 17 : CentralLogger.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.10;

/// @title Central logger contract
/// @notice Log collector with only 1 purpose - to emit the event. Can be called from any contract
/** @dev Use like this:
*
* bytes32 internal constant CENTRAL_LOGGER_ID = keccak256("CentralLogger");
* CentralLogger logger = CentralLogger(Registry(registry).getAddress(CENTRAL_LOGGER_ID));
*
* Or directly:
*   CentralLogger logger = CentralLogger(0xDEPLOYEDADDRESS);
*
* logger.log(
*            address(this),
*            msg.sender,
*            "myGreatFunction",
*            abi.encode(msg.value, param1, param2)
*        );
*
* DO NOT USE delegateCall as it defies the centralisation purpose of this logger.
*/
contract CentralLogger {

    event LogEvent(
        address indexed contractAddress,
        address indexed caller,
        string indexed logName,
        bytes data
    );

	/* solhint-disable no-empty-blocks */
	constructor() {
	}

    /// @notice Log the event centrally
    /// @dev For gas impact see https://www.evm.codes/#a3
    /// @param _logName length must be less than 32 bytes
    function log(
        address _contract,
        address _caller,
        string memory _logName,
        bytes memory _data
    ) public {
        emit LogEvent(_contract, _caller, _logName, _data);
    }
}

File 4 of 17 : CommunityAcknowledgement.sol
// SPDX-License-Identifier: LGPL-3.0
pragma solidity =0.8.10;

import "./Ownable.sol";

contract CommunityAcknowledgement is Ownable {

	/// @notice Recognised Community Contributor Acknowledgement Rate
	/// @dev Id is keccak256 hash of contributor address
	mapping (bytes32 => uint16) public rccar;

	/// @notice Emit when owner recognises contributor
	/// @param contributor Keccak256 hash of recognised contributor address
	/// @param previousAcknowledgementRate Previous contributor acknowledgement rate
	/// @param newAcknowledgementRate New contributor acknowledgement rate
	event ContributorRecognised(bytes32 indexed contributor, uint16 indexed previousAcknowledgementRate, uint16 indexed newAcknowledgementRate);

	/* solhint-disable-next-line no-empty-blocks */
	constructor(address _adoptionDAOAddress) Ownable(_adoptionDAOAddress) {

	}

	/// @notice Getter for Recognised Community Contributor Acknowledgement Rate
	/// @param _contributor Keccak256 hash of contributor address
	/// @return Acknowledgement Rate
	function getAcknowledgementRate(bytes32 _contributor) external view returns (uint16) {
		return rccar[_contributor];
	}

	/// @notice Getter for Recognised Community Contributor Acknowledgement Rate for msg.sender
	/// @return Acknowledgement Rate
	function senderAcknowledgementRate() external view returns (uint16) {
		return rccar[keccak256(abi.encodePacked(msg.sender))];
	}

	/// @notice Recognise community contributor and set its acknowledgement rate
	/// @dev Only owner can recognise contributor
	/// @dev Emits `ContributorRecognised` event
	/// @param _contributor Keccak256 hash of recognised contributor address
	/// @param _acknowledgementRate Contributor new acknowledgement rate
	function recogniseContributor(bytes32 _contributor, uint16 _acknowledgementRate) public onlyOwner {
		uint16 _previousAcknowledgementRate = rccar[_contributor];
		rccar[_contributor] = _acknowledgementRate;
		emit ContributorRecognised(_contributor, _previousAcknowledgementRate, _acknowledgementRate);
	}

	/// @notice Recognise list of contributors
	/// @dev Only owner can recognise contributors
	/// @dev Emits `ContributorRecognised` event for every contributor
	/// @param _contributors List of keccak256 hash of recognised contributor addresses
	/// @param _acknowledgementRates List of contributors new acknowledgement rates
	function batchRecogniseContributor(bytes32[] calldata _contributors, uint16[] calldata _acknowledgementRates) external onlyOwner {
		require(_contributors.length == _acknowledgementRates.length, "Lists do not match in length");

		for (uint256 i = 0; i < _contributors.length; i++) {
			recogniseContributor(_contributors[i], _acknowledgementRates[i]);
		}
	}

}

File 5 of 17 : Config.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

import "./Ownable.sol";

/// @title APUS config contract
/// @notice Holds global variables for the rest of APUS ecosystem
contract Config is Ownable {

	/// @notice Adoption Contribution Rate, where 100% = 10000 = ACR_DECIMAL_PRECISION. 
	/// @dev Percent value where 0 -> 0%, 10 -> 0.1%, 100 -> 1%, 250 -> 2.5%, 550 -> 5.5%, 1000 -> 10%, 0xffff -> 655.35%
	/// @dev Example: x * adoptionContributionRate / ACR_DECIMAL_PRECISION
	uint16 public adoptionContributionRate;

	/// @notice Adoption DAO multisig address
	address payable public adoptionDAOAddress;

	/// @notice Emit when owner changes Adoption Contribution Rate
	/// @param caller Who changed the Adoption Contribution Rate (i.e. who was owner at that moment)
	/// @param previousACR Previous Adoption Contribution Rate
	/// @param newACR New Adoption Contribution Rate
	event ACRChanged(address indexed caller, uint16 previousACR, uint16 newACR);

	/// @notice Emit when owner changes Adoption DAO address
	/// @param caller Who changed the Adoption DAO address (i.e. who was owner at that moment)
	/// @param previousAdoptionDAOAddress Previous Adoption DAO address
	/// @param newAdoptionDAOAddress New Adoption DAO address
	event AdoptionDAOAddressChanged(address indexed caller, address previousAdoptionDAOAddress, address newAdoptionDAOAddress);

	/* solhint-disable-next-line func-visibility */
	constructor(address payable _adoptionDAOAddress, uint16 _initialACR) Ownable(_adoptionDAOAddress) {
		adoptionContributionRate = _initialACR;
		adoptionDAOAddress = _adoptionDAOAddress;
	}


	/// @notice Change Adoption Contribution Rate
	/// @dev Only owner can change Adoption Contribution Rate
	/// @dev Emits `ACRChanged` event
	/// @param _newACR Adoption Contribution Rate
	function setAdoptionContributionRate(uint16 _newACR) external onlyOwner {
		uint16 _previousACR = adoptionContributionRate;
		adoptionContributionRate = _newACR;
		emit ACRChanged(msg.sender, _previousACR, _newACR);
	}

	/// @notice Change Adoption DAO address
	/// @dev Only owner can change Adoption DAO address
	/// @dev Emits `AdoptionDAOAddressChanged` event
	function setAdoptionDAOAddress(address payable _newAdoptionDAOAddress) external onlyOwner {
		address payable _previousAdoptionDAOAddress = adoptionDAOAddress;
		adoptionDAOAddress = _newAdoptionDAOAddress;
		emit AdoptionDAOAddressChanged(msg.sender, _previousAdoptionDAOAddress, _newAdoptionDAOAddress);
	}

}

File 6 of 17 : LiquityMath.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "./BaseMath.sol";

/// @title Business calculation logic related to the Liquity protocol
/// @dev To be inherited only
contract LiquityMath is BaseMath {

    // Maximum protocol fee as defined in the Liquity contracts
    // https://github.com/liquity/dev/blob/cb583ddf5e7de6010e196cfe706bd0ca816ea40e/packages/contracts/contracts/TroveManager.sol#L48
    uint256 internal constant LIQUITY_PROTOCOL_MAX_BORROWING_FEE = DECIMAL_PRECISION / 100 * 5; // 5%

    // Amount of LUSD to be locked in Liquity's gas pool on opening troves
    // https://github.com/liquity/dev/blob/cb583ddf5e7de6010e196cfe706bd0ca816ea40e/packages/contracts/contracts/TroveManager.sol#L334
    uint256 internal constant LIQUITY_LUSD_GAS_COMPENSATION = 200e18;

	/// @notice Calculates the needed amount of LUSD parameter for Liquity protocol when borrowing LUSD
    /// @param _LUSDRequestedAmount Amount the user wants to withdraw
    /// @param _expectedLiquityProtocolRate Current / expected borrowing rate of the Liquity protocol
    /// @param _adoptionContributionRate Adoption Contribution Rate in uint16 form (xxyy defines xx.yy %). LPR is applied when ACR < LPR. Thus LPR is always used When AR is set to 0.
    /* solhint-disable-next-line var-name-mixedcase */
    function calcNeededLiquityLUSDAmount(uint256 _LUSDRequestedAmount, uint256 _expectedLiquityProtocolRate, uint16 _adoptionContributionRate) internal pure returns (
        uint256 neededLiquityLUSDAmount
    ) {

        // Normalise ACR 1e4 -> 1e18
        uint256 acr = DECIMAL_PRECISION / ACR_DECIMAL_PRECISION * _adoptionContributionRate;

        // Apply Liquity protocol rate when ACR is lower
        acr = acr < _expectedLiquityProtocolRate ? _expectedLiquityProtocolRate : acr;

        // Includes requested debt and adoption contribution which covers also liquity protocol fee
        uint256 expectedDebtToRepay = _LUSDRequestedAmount * acr / DECIMAL_PRECISION + _LUSDRequestedAmount;

        // = x / ( 1 + fee rate<0.005 - 0.05> )
        neededLiquityLUSDAmount = DECIMAL_PRECISION * expectedDebtToRepay / ( DECIMAL_PRECISION + _expectedLiquityProtocolRate ); 

        require(neededLiquityLUSDAmount >= _LUSDRequestedAmount, "Cannot mint less than requested.");
    }

    /// @notice Calculates adjusted Adoption Contribution Rate decreased by RCCAR down to min 0.
    /// @param _rccar Recognised Community Contributor Acknowledgement Rate in uint16 form (xxyy defines xx.yy % points).
    /// @param _adoptionContributionRate Adoption Contribution Rate in uint16 form (xxyy defines xx.yy %).
    function applyRccarOnAcr(uint16 _rccar, uint16 _adoptionContributionRate) internal pure returns (
        uint16 adjustedAcr
    ) {
        return (_adoptionContributionRate > _rccar ? _adoptionContributionRate - _rccar : 0);
    }
}

File 7 of 17 : Ownable.sol
// SPDX-License-Identifier: MIT
// Adapted from OpenZeppelin Contracts v4.4.0 (access/Ownable.sol)
// Using less gas and initiating the first owner to the provided multisig address

pragma solidity ^0.8.10;

/**
 * @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.
 *
 * By default, the owner account will be the one provided during the deployment of the contract. 
 * This can later be changed with {transferOwnership}.
 *
 * 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 Ownable {

    /**
     * @dev Address of the current owner. 
     */
    address public owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @param _firstOwner Initial owner
     * @dev Initializes the contract setting the initial owner.
     */
    constructor(address _firstOwner) {
        _transferOwnership(_firstOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner == msg.sender, "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address _newOwner) public virtual onlyOwner {
        require(_newOwner != address(0), "Ownable: cannot be zero address");
        _transferOwnership(_newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address _newOwner) internal virtual {
        address oldOwner = owner;
        owner = _newOwner;
        emit OwnershipTransferred(oldOwner, _newOwner);
    }
}

File 8 of 17 : Registry.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

import "./Ownable.sol";

/// @title Registry contract for whole Apus ecosystem
/// @notice Holds addresses of all essential Apus contracts
contract Registry is Ownable {

	/// @notice Stores address under its id
	/// @dev Id is keccak256 hash of its string representation
	mapping (bytes32 => address) public addresses;

	/// @notice Emit when owner registers address
	/// @param id Keccak256 hash of its string id representation
	/// @param previousAddress Previous address value under given id
	/// @param newAddress New address under given id
	event AddressRegistered(bytes32 indexed id, address indexed previousAddress, address indexed newAddress);

	/* solhint-disable-next-line no-empty-blocks */
	constructor(address _initialOwner) Ownable(_initialOwner) {

	}


	/// @notice Getter for registered addresses
	/// @dev Returns zero address if address have not been registered before
	/// @param _id Registered address identifier
	function getAddress(bytes32 _id) external view returns(address) {
		return addresses[_id];
	}


	/// @notice Register address under given id
	/// @dev Only owner can register addresses
	/// @dev Emits `AddressRegistered` event
	/// @param _id Keccak256 hash of its string id representation
	/// @param _address Registering address
	function registerAddress(bytes32 _id, address _address) public onlyOwner {
		require(_address != address(0), "Can't register 0x0 address");
		address _previousAddress = addresses[_id];
		addresses[_id] = _address;
		emit AddressRegistered(_id, _previousAddress, _address);
	}

	/// @notice Register list of addresses under given list of ids
	/// @dev Only owner can register addresses
	/// @dev Emits `AddressRegistered` event for every address
	/// @param _ids List of keccak256 hashes of its string id representation
	/// @param _addresses List of registering addresses
	function batchRegisterAddresses(bytes32[] calldata _ids, address[] calldata _addresses) external onlyOwner {
		require(_ids.length == _addresses.length, "Lists do not match in length");

		for (uint256 i = 0; i < _ids.length; i++) {
			registerAddress(_ids[i], _addresses[i]);
		}
	}
}

File 9 of 17 : SqrtMath.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

contract SqrtMath {

    /// @notice Calculates the square root of x, rounding down.
    /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.
    ///
    /// Caveats:
    /// - This function does not work with fixed-point numbers.
    ///
    /// @param x The uint256 number for which to calculate the square root.
    /// @return result The result as an uint256.
    // source: https://github.com/paulrberg/prb-math/blob/86c068e21f9ba229025a77b951bd3c4c4cf103da/contracts/PRBMath.sol#L591
    function sqrt(uint256 x) internal pure returns (uint256 result) {
        if (x == 0) {
            return 0;
        }

        // Set the initial guess to the least power of two that is greater than or equal to sqrt(x).
        uint256 xAux = uint256(x);
        result = 1;
        if (xAux >= 0x100000000000000000000000000000000) {
            xAux >>= 128;
            result <<= 64;
        }
        if (xAux >= 0x10000000000000000) {
            xAux >>= 64;
            result <<= 32;
        }
        if (xAux >= 0x100000000) {
            xAux >>= 32;
            result <<= 16;
        }
        if (xAux >= 0x10000) {
            xAux >>= 16;
            result <<= 8;
        }
        if (xAux >= 0x100) {
            xAux >>= 8;
            result <<= 4;
        }
        if (xAux >= 0x10) {
            xAux >>= 4;
            result <<= 2;
        }
        if (xAux >= 0x8) {
            result <<= 1;
        }

        // The operations can never overflow because the result is max 2^127 when it enters this block.
        unchecked {
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1; // Seven iterations should be enough
            uint256 roundedDownResult = x / result;
            return result >= roundedDownResult ? roundedDownResult : result;
        }
    }

}

File 10 of 17 : DSAuth.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

import "./DSAuthority.sol";

contract DSAuthEvents {
    event LogSetAuthority(address indexed authority);
    event LogSetOwner(address indexed owner);
}

abstract contract DSAuth is DSAuthEvents {
    DSAuthority public authority;
    address public owner;

    constructor() {
        owner = msg.sender;
        emit LogSetOwner(msg.sender);
    }

    function setOwner(address owner_) public virtual;

    function setAuthority(DSAuthority authority_) public virtual;

    function isAuthorized(address src, bytes4 sig) internal view virtual returns (bool);
}

File 11 of 17 : DSAuthority.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

abstract contract DSAuthority {
    function canCall(
        address src,
        address dst,
        bytes4 sig
    ) public view virtual returns (bool);
}

File 12 of 17 : DSProxy.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

import "./DSAuth.sol";

abstract contract DSProxy is DSAuth {
    DSProxyCache public cache; // global cache for contracts

    constructor(address _cacheAddr) {
        require(setCache(_cacheAddr), "Cache not set");
    }

    // solhint-disable-next-line no-empty-blocks
    receive() external payable {}

    // use the proxy to execute calldata _data on contract _code
    function execute(bytes memory _code, bytes memory _data)
        public
        payable
        virtual
        returns (address target, bytes32 response);

    function execute(address _target, bytes memory _data)
        public
        payable
        virtual
        returns (bytes32 response);

    //set new cache
    function setCache(address _cacheAddr) public payable virtual returns (bool);
}

abstract contract DSProxyCache {
    mapping(bytes32 => address) cache;

    function read(bytes memory _code) public view virtual returns (address);

    function write(bytes memory _code) public virtual returns (address target);
}

File 13 of 17 : DSProxyFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

import "./DSProxy.sol";

abstract contract DSProxyFactory {
    function build(address owner) public virtual returns (DSProxy proxy);
    function build() public virtual returns (DSProxy proxy);
    function isProxy(address proxy) public virtual view returns (bool);
}

File 14 of 17 : ICollSurplusPool.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.10;


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 15 of 17 : IHintHelpers.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.10;

interface IHintHelpers {

    function getRedemptionHints(
        uint _LUSDamount, 
        uint _price,
        uint _maxIterations
    )
        external
        view
        returns (
            address firstRedemptionHint,
            uint partialRedemptionHintNICR,
            uint truncatedLUSDamount
        );

    function getApproxHint(uint _CR, uint _numTrials, uint _inputRandomSeed)
        external
        view
        returns (address hintAddress, uint diff, uint latestRandomSeed);

    function computeNominalCR(uint _coll, uint _debt) external pure returns (uint);

    function computeCR(uint _coll, uint _debt, uint _price) external pure returns (uint);
}

File 16 of 17 : ISortedTroves.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.10;

// 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 17 of 17 : ITroveManager.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.10;


// Common interface for the Trove Manager.
interface ITroveManager {
    
    // --- 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 LQTYTokenAddressChanged(address _lqtyTokenAddress);
    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);

    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);

    function Troves(address) external view returns (uint256, uint256, uint256, uint8, uint128); 
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_registry","type":"address"},{"internalType":"address","name":"_troveManager","type":"address"},{"internalType":"address","name":"_hintHelpers","type":"address"},{"internalType":"address","name":"_sortedTroves","type":"address"},{"internalType":"address","name":"_collSurplusPool","type":"address"},{"internalType":"address","name":"_proxyFactory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"smartAccountAddress","type":"address"}],"name":"SmartAccountCreated","type":"event"},{"inputs":[],"name":"CollSurplusPool","outputs":[{"internalType":"contract ICollSurplusPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HintHelpers","outputs":[{"internalType":"contract IHintHelpers","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ProxyFactory","outputs":[{"internalType":"contract DSProxyFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SortedTroves","outputs":[{"internalType":"contract ISortedTroves","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TroveManager","outputs":[{"internalType":"contract ITroveManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"addCollateralLiquity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isDebtIncrease","type":"bool"},{"internalType":"uint256","name":"_LUSDRequestedChange","type":"uint256"},{"internalType":"address","name":"_LUSDAddress","type":"address"},{"internalType":"uint256","name":"_collWithdrawal","type":"uint256"},{"internalType":"address payable","name":"_collateralTo","type":"address"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"adjustCreditLineLiquity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_LUSDRequestedChange","type":"uint256"},{"internalType":"address","name":"_LUSDFrom","type":"address"},{"internalType":"uint256","name":"_collWithdrawal","type":"uint256"},{"internalType":"address payable","name":"_collateralTo","type":"address"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"adjustCreditLineLiquityWithPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_LUSDRequestedChange","type":"uint256"},{"internalType":"address","name":"_LUSDTo","type":"address"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"borrowLUSDLiquity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isDebtIncrease","type":"bool"},{"internalType":"uint256","name":"_LUSDRequestedChange","type":"uint256"},{"internalType":"bool","name":"_isCollateralIncrease","type":"bool"},{"internalType":"uint256","name":"_collateralChange","type":"uint256"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"calculateChangedLiquityParameters","outputs":[{"internalType":"uint256","name":"newCollateral","type":"uint256"},{"internalType":"uint256","name":"expectedDebtToRepay","type":"uint256"},{"internalType":"uint256","name":"liquidationReserve","type":"uint256"},{"internalType":"uint256","name":"expectedCompositeDebtLiquity","type":"uint256"},{"internalType":"uint256","name":"NICR","type":"uint256"},{"internalType":"address","name":"upperHint","type":"address"},{"internalType":"address","name":"lowerHint","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_LUSDRequested","type":"uint256"},{"internalType":"uint256","name":"_collateralAmount","type":"uint256"}],"name":"calculateInitialLiquityParameters","outputs":[{"internalType":"uint256","name":"expectedDebtToRepay","type":"uint256"},{"internalType":"uint256","name":"liquidationReserve","type":"uint256"},{"internalType":"uint256","name":"expectedCompositeDebtLiquity","type":"uint256"},{"internalType":"uint256","name":"NICR","type":"uint256"},{"internalType":"address","name":"upperHint","type":"address"},{"internalType":"address","name":"lowerHint","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_smartAccount","type":"address"}],"name":"checkClaimableCollateralLiquity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"_collateralTo","type":"address"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"claimRemainingCollateralLiquity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_LUSDFrom","type":"address"},{"internalType":"address payable","name":"_collateralTo","type":"address"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"closeCreditLineLiquity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_LUSDFrom","type":"address"},{"internalType":"address payable","name":"_collateralTo","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"closeCreditLineLiquityWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"getCreditLineStatusLiquity","outputs":[{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"uint256","name":"collateral","type":"uint256"},{"internalType":"uint256","name":"debtToRepay","type":"uint256"},{"internalType":"uint256","name":"debtComposite","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_LUSDRequested","type":"uint256"},{"internalType":"address","name":"_LUSDTo","type":"address"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"openCreditLineLiquity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"openSmartAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_LUSDRequestedChange","type":"uint256"},{"internalType":"address","name":"_LUSDFrom","type":"address"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"repayLUSDLiquity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_LUSDRequestedChange","type":"uint256"},{"internalType":"address","name":"_LUSDFrom","type":"address"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"repayLUSDLiquityWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"userAdoptionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collWithdrawal","type":"uint256"},{"internalType":"address payable","name":"_collateralTo","type":"address"},{"internalType":"address","name":"_upperHint","type":"address"},{"internalType":"address","name":"_lowerHint","type":"address"},{"internalType":"address payable","name":"_smartAccount","type":"address"}],"name":"withdrawCollateralLiquity","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101406040523480156200001257600080fd5b506040516200250438038062002504833981016040819052620000359162000082565b6001600160a01b0395861660805293851660c05291841660e0528316610100528216610120521660a05262000103565b80516001600160a01b03811681146200007d57600080fd5b919050565b60008060008060008060c087890312156200009c57600080fd5b620000a78762000065565b9550620000b76020880162000065565b9450620000c76040880162000065565b9350620000d76060880162000065565b9250620000e76080880162000065565b9150620000f760a0880162000065565b90509295509295509295565b60805160a05160c05160e0516101005161012051612348620001bc6000396000818161029c015261099a0152600081816103800152818161138801526114f20152600081816102680152611455015260008181610318015281816108d001528181610ad70152818161130001526117e301526000818161016b0152610d7201526000818161034c01528181610e3701528181610fc8015281816111af015281816115af01528181611707015261187e01526123486000f3fe60806040526004361061013f5760003560e01c806369a02818116100b6578063c410654b1161006f578063c410654b14610429578063c892a63014610449578063caa5f62514610469578063e0abde72146104ca578063eb14f505146104dd578063f520b3a4146104fd57600080fd5b806369a02818146103065780637b1039991461033a578063b15c40001461036e578063ba45369c146103a2578063bd64061f146103c5578063c20b24f61461040957600080fd5b8063422c9e9e11610108578063422c9e9e146101fd5780634acd820e146102565780635915b3a41461028a5780635d83dc39146102be5780636239615d146102de5780636559b765146102f157600080fd5b8062b748ee1461014457806301c0489c1461015957806304f14191146101aa5780631751ce63146101ca57806338e6e5e4146101dd575b600080fd5b610157610152366004611c39565b61051d565b005b34801561016557600080fd5b5061018d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101b657600080fd5b506101576101c5366004611cb0565b61058f565b6101576101d8366004611d3e565b61061c565b3480156101e957600080fd5b506101576101f8366004611dea565b6106bb565b34801561020957600080fd5b5061021d610218366004611e23565b610712565b6040805196875260208701959095529385019290925260608401526001600160a01b0390811660808401521660a082015260c0016101a1565b34801561026257600080fd5b5061018d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561029657600080fd5b5061018d7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102ca57600080fd5b506101576102d9366004611c39565b61077c565b6101576102ec366004611e5a565b6107ca565b3480156102fd57600080fd5b5061015761084d565b34801561031257600080fd5b5061018d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561034657600080fd5b5061018d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561037a57600080fd5b5061018d7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103ae57600080fd5b506103b7610858565b6040519081526020016101a1565b3480156103d157600080fd5b506103e56103e0366004611ede565b6108a8565b6040805160ff909516855260208501939093529183015260608201526080016101a1565b34801561041557600080fd5b506103b7610424366004611ede565b610978565b34801561043557600080fd5b50610157610444366004611efb565b610a0d565b34801561045557600080fd5b50610157610464366004611c39565b610a6d565b34801561047557600080fd5b50610489610484366004611f46565b610abb565b60408051978852602088019690965294860193909352606085019190915260808401526001600160a01b0390811660a08401521660c082015260e0016101a1565b6101576104d8366004611efb565b610c3e565b3480156104e957600080fd5b506101576104f8366004611c39565b610c98565b34801561050957600080fd5b50610157610518366004611f93565b610cf3565b6001600160a01b03811615610532578061053a565b61053a610d6d565b90506105888134878787873360405160240161055a959493929190612003565b60408051601f198184030181529190526020810180516001600160e01b0316625ba47760e11b1790526110d5565b5050505050565b604051602481018990526001600160a01b03808916604483015280881660648301528616608482015260ff851660a482015260c4810184905260e48101839052336101048201526106129082906000906101240160408051601f198184030181529190526020810180516001600160e01b03166304f1419160e01b1790526110d5565b5050505050505050565b604051602481018b90526001600160a01b03808b166044830152606482018a9052808916608483015280881660a4830152861660c482015260ff851660e482015261010481018490526101248101839052336101448201526106af90829034906101640160408051601f198184030181529190526020810180516001600160e01b0316631751ce6360e01b1790526110d5565b50505050505050505050565b6040516001600160a01b038316602482015233604482015261070e90829060009060640160408051601f198184030181529190526020810180516001600160e01b0316630e39b97960e21b1790526110d5565b5050565b6000680ad78ebc5ac62000008180808061072b886112bd565b9550610740680ad78ebc5ac620000087612047565b9350836107568868056bc75e2d6310000061205f565b6107609190612094565b925061076b83611381565b969995985093965091949293915050565b610588816000878787873360405160240161079b959493929190612003565b60408051601f198184030181529190526020810180516001600160e01b0316635d83dc3960e01b1790526110d5565b6040518815156024820152604481018890526001600160a01b0380881660648301526084820187905280861660a483015280851660c4830152831660e4820152336101048201526106129082903490610124015b60408051601f198184030181529190526020810180516001600160e01b0316636239615d60e01b1790526110d5565b610855610d6d565b50565b600080600061086561156b565b9092509050600061ffff8316610885612710670de0b6b3a7640000612094565b61088f919061205f565b905081811061089e57806108a0565b815b935050505090565b604051630ddec86760e31b81526001600160a01b0382811660048301526000918291829182917f00000000000000000000000000000000000000000000000000000000000000001690636ef643389060240160a060405180830381865afa158015610917573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093b91906120b6565b50965090945090915050680ad78ebc5ac6200000811161095c57600061096f565b61096f680ad78ebc5ac620000082612114565b91509193509193565b604051639b56d6c960e01b81526001600160a01b0382811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690639b56d6c990602401602060405180830381865afa1580156109e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a07919061212b565b92915050565b6040516001600160a01b03808516602483015283166044820152336064820152610a6890829060009060840160408051601f198184030181529190526020810180516001600160e01b031663c410654b60e01b1790526110d5565b505050565b6105888160008787878733604051602401610a8c959493929190612003565b60408051601f198184030181529190526020810180516001600160e01b0316630c892a6360e41b1790526110d5565b6000806000806000806000680ad78ebc5ac620000094506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b91af97c8b6040518263ffffffff1660e01b8152600401610b3091906001600160a01b0391909116815260200190565b608060405180830381865afa158015610b4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b719190612144565b5050915091506000680ad78ebc5ac620000083610b8e9190612114565b90508c15610ba757610ba08c83612047565b9950610bb4565b610bb18c83612114565b99505b8e15610bd9576000610bc58f6112bd565b9050610bd18183612047565b995050610be6565b610be38e82612114565b98505b610bf9680ad78ebc5ac62000008a612047565b965086610c0f8b68056bc75e2d6310000061205f565b610c199190612094565b9550610c2486611381565b8095508196505050505050959b949a509550955095509550565b6040516001600160a01b03808516602483015283166044820152336064820152610a68908290349060840160408051601f198184030181529190526020810180516001600160e01b0316637055ef3960e11b17905261186c565b60405160016024820152604481018690526001600160a01b0380861660648301526000608483018190523360a4840181905282871660c485015291851660e4840152610104830191909152610588918391906101240161081e565b6040516001600160a01b0380881660248301528616604482015260ff851660648201526084810184905260a481018390523360c4820152610d6590829060009060e40160408051601f198184030181529190526020810180516001600160e01b0316633d482ce960e21b1790526110d5565b505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638e1a55fc6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df4919061217a565b6040516321f8a72160e01b81527f8b16b0b80f67879a61157c5541d94886825d45098bee58e37e2d2e87b2fe367b60048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906321f8a72190602401602060405180830381865afa158015610e7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea2919061217a565b604051637a9e5e4b60e01b81526001600160a01b03808316600483015291925090831690637a9e5e4b90602401600060405180830381600087803b158015610ee957600080fd5b505af1158015610efd573d6000803e3d6000fd5b50506040516313af403560e01b81523360048201526001600160a01b03851692506313af40359150602401600060405180830381600087803b158015610f4257600080fd5b505af1158015610f56573d6000803e3d6000fd5b50506040516001600160a01b03851692503391507f11f81d728010658858b98bd3e5ece1f1a7a9caf6fb57f3742794cfc1c1e8aa9090600090a36040516321f8a72160e01b81527fe02f0ae036ce53d23638e7b8f91c7b58ddb5bb2ac782194ca7ae5ff0826a8c6f60048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa158015611017573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103b919061217a565b9050806001600160a01b03166385d3a13230338660405160200161106e91906001600160a01b0391909116815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161109b939291906121e4565b600060405180830381600087803b1580156110b557600080fd5b505af11580156110c9573d6000803e3d6000fd5b50949695505050505050565b82336001600160a01b0316816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561111e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611142919061217a565b6001600160a01b03161461119d5760405162461bcd60e51b815260206004820152601c60248201527f53656e6465722068617320746f2062652070726f7879206f776e65720000000060448201526064015b60405180910390fd5b836001600160a01b0316631cff79cd847f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166321f8a7217feb35d5f9843d4076628c4747d195abdd0312e0b8b8f5812a706f3d25ea0b10746040518263ffffffff1660e01b815260040161121b91815260200190565b602060405180830381865afa158015611238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125c919061217a565b856040518463ffffffff1660e01b815260040161127a929190612241565b60206040518083038185885af1158015611298573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610588919061212b565b60008060006112ca61156b565b909250905060006112dc858385611992565b60405163477d66cf60e01b8152600481018290529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063477d66cf90602401602060405180830381865afa158015611347573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136b919061212b565b90506113778183612047565b9695505050505050565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663de8fa4316040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611408919061212b565b9050600061141582611a80565b61142090600f61205f565b604051633da0dedf60e11b81526004810187905260248101829052634150555360448201529091506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637b41bdbe90606401606060405180830381865afa15801561149c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c09190612265565b505060405163105a603760e21b8152600481018890526001600160a01b038083166024830181905260448301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063416980dc906064016040805180830381865afa15801561153a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155e919061229c565b9097909650945050505050565b6040516321f8a72160e01b81527f4783a7bf568159da8dab9963f361ffb520fa09d911fcf017b1a7273038b176406004820152600090819081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906321f8a72190602401602060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061217a565b6040516bffffffffffffffffffffffff193360601b1660208201529091506000906001600160a01b0383169063597211b090603401604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161168391815260200190565b602060405180830381865afa1580156116a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c491906122cb565b6040516321f8a72160e01b81527f48fd0b937c5f6bca9b37c93d4dfaa4c645a0d160ca5949ee15270fd6936c924b60048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906321f8a72190602401602060405180830381865afa15801561174e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611772919061217a565b90506117df82826001600160a01b03166349208e026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117da91906122cb565b611bfb565b94507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166366ca4a216040518163ffffffff1660e01b8152600401602060405180830381865afa15801561183f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611863919061212b565b93505050509091565b826001600160a01b0316631cff79cd837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166321f8a7217feb35d5f9843d4076628c4747d195abdd0312e0b8b8f5812a706f3d25ea0b10746040518263ffffffff1660e01b81526004016118ea91815260200190565b602060405180830381865afa158015611907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192b919061217a565b846040518463ffffffff1660e01b8152600401611949929190612241565b60206040518083038185885af1158015611967573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061198c919061212b565b50505050565b60008061ffff83166119ae612710670de0b6b3a7640000612094565b6119b8919061205f565b90508381106119c757806119c9565b835b9050600085670de0b6b3a76400006119e1848361205f565b6119eb9190612094565b6119f59190612047565b9050611a0985670de0b6b3a7640000612047565b611a1b82670de0b6b3a764000061205f565b611a259190612094565b925085831015611a775760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f74206d696e74206c657373207468616e207265717565737465642e6044820152606401611194565b50509392505050565b600081611a8f57506000919050565b50600181600160801b8110611aa95760409190911b9060801c5b680100000000000000008110611ac45760209190911b9060401c5b6401000000008110611adb5760109190911b9060201c5b620100008110611af05760089190911b9060101c5b6101008110611b045760049190911b9060081c5b60108110611b175760029190911b9060041c5b60088110611b2757600182901b91505b6001828481611b3857611b3861207e565b048301901c91506001828481611b5057611b5061207e565b048301901c91506001828481611b6857611b6861207e565b048301901c91506001828481611b8057611b8061207e565b048301901c91506001828481611b9857611b9861207e565b048301901c91506001828481611bb057611bb061207e565b048301901c91506001828481611bc857611bc861207e565b048301901c91506000828481611be057611be061207e565b04905080831015611bf15782611bf3565b805b949350505050565b60008261ffff168261ffff1611611c13576000611c1d565b611c1d83836122ef565b9392505050565b6001600160a01b038116811461085557600080fd5b600080600080600060a08688031215611c5157600080fd5b853594506020860135611c6381611c24565b93506040860135611c7381611c24565b92506060860135611c8381611c24565b91506080860135611c9381611c24565b809150509295509295909350565b60ff8116811461085557600080fd5b600080600080600080600080610100898b031215611ccd57600080fd5b883597506020890135611cdf81611c24565b96506040890135611cef81611c24565b95506060890135611cff81611c24565b94506080890135611d0f81611ca1565b935060a0890135925060c0890135915060e0890135611d2d81611c24565b809150509295985092959890939650565b6000806000806000806000806000806101408b8d031215611d5e57600080fd5b8a35995060208b0135611d7081611c24565b985060408b0135975060608b0135611d8781611c24565b965060808b0135611d9781611c24565b955060a08b0135611da781611c24565b945060c08b0135611db781611ca1565b935060e08b013592506101008b013591506101208b0135611dd781611c24565b809150509295989b9194979a5092959850565b60008060408385031215611dfd57600080fd5b8235611e0881611c24565b91506020830135611e1881611c24565b809150509250929050565b60008060408385031215611e3657600080fd5b50508035926020909101359150565b80358015158114611e5557600080fd5b919050565b600080600080600080600080610100898b031215611e7757600080fd5b611e8089611e45565b9750602089013596506040890135611e9781611c24565b9550606089013594506080890135611eae81611c24565b935060a0890135611ebe81611c24565b925060c0890135611ece81611c24565b915060e0890135611d2d81611c24565b600060208284031215611ef057600080fd5b8135611c1d81611c24565b600080600060608486031215611f1057600080fd5b8335611f1b81611c24565b92506020840135611f2b81611c24565b91506040840135611f3b81611c24565b809150509250925092565b600080600080600060a08688031215611f5e57600080fd5b611f6786611e45565b945060208601359350611f7c60408701611e45565b9250606086013591506080860135611c9381611c24565b60008060008060008060c08789031215611fac57600080fd5b8635611fb781611c24565b95506020870135611fc781611c24565b94506040870135611fd781611ca1565b9350606087013592506080870135915060a0870135611ff581611c24565b809150509295509295509295565b9485526001600160a01b03938416602086015291831660408501528216606084015216608082015260a00190565b634e487b7160e01b600052601160045260246000fd5b6000821982111561205a5761205a612031565b500190565b600081600019048311821515161561207957612079612031565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826120b157634e487b7160e01b600052601260045260246000fd5b500490565b600080600080600060a086880312156120ce57600080fd5b85519450602086015193506040860151925060608601516120ee81611ca1565b60808701519092506fffffffffffffffffffffffffffffffff81168114611c9357600080fd5b60008282101561212657612126612031565b500390565b60006020828403121561213d57600080fd5b5051919050565b6000806000806080858703121561215a57600080fd5b505082516020840151604085015160609095015191969095509092509050565b60006020828403121561218c57600080fd5b8151611c1d81611c24565b6000815180845260005b818110156121bd576020818501810151868301820152016121a1565b818111156121cf576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b038481168252831660208201526080604082018190526010908201526f1bdc195b94db585c9d1058d8dbdd5b9d60821b60a082015260c06060820181905260009061223890830184612197565b95945050505050565b6001600160a01b0383168152604060208201819052600090611bf390830184612197565b60008060006060848603121561227a57600080fd5b835161228581611c24565b602085015160409095015190969495509392505050565b600080604083850312156122af57600080fd5b82516122ba81611c24565b6020840151909250611e1881611c24565b6000602082840312156122dd57600080fd5b815161ffff81168114611c1d57600080fd5b600061ffff8381169083168181101561230a5761230a612031565b03939250505056fea264697066735822122078bddd6ceaf72b058d267ba845ccbd54b29f21e9ce281a28c452f5ec59b71bed64736f6c634300080a0033000000000000000000000000e19968d1cdcf71651a6131b26acc6c23bc12192c000000000000000000000000a39739ef8b0231dbfa0dcda07d7e29faabcf4bb2000000000000000000000000e84251b93d9524e0d2e621ba7dc7cb3579f997c00000000000000000000000008fdd3fbfeb32b28fb73555518f8b361bcea741a60000000000000000000000003d32e8b97ed5881324241cf03b2da5e2ebce5521000000000000000000000000a26e15c895efc0616177b7c1e7270a4c7d51c997

Deployed Bytecode

0x60806040526004361061013f5760003560e01c806369a02818116100b6578063c410654b1161006f578063c410654b14610429578063c892a63014610449578063caa5f62514610469578063e0abde72146104ca578063eb14f505146104dd578063f520b3a4146104fd57600080fd5b806369a02818146103065780637b1039991461033a578063b15c40001461036e578063ba45369c146103a2578063bd64061f146103c5578063c20b24f61461040957600080fd5b8063422c9e9e11610108578063422c9e9e146101fd5780634acd820e146102565780635915b3a41461028a5780635d83dc39146102be5780636239615d146102de5780636559b765146102f157600080fd5b8062b748ee1461014457806301c0489c1461015957806304f14191146101aa5780631751ce63146101ca57806338e6e5e4146101dd575b600080fd5b610157610152366004611c39565b61051d565b005b34801561016557600080fd5b5061018d7f000000000000000000000000a26e15c895efc0616177b7c1e7270a4c7d51c99781565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101b657600080fd5b506101576101c5366004611cb0565b61058f565b6101576101d8366004611d3e565b61061c565b3480156101e957600080fd5b506101576101f8366004611dea565b6106bb565b34801561020957600080fd5b5061021d610218366004611e23565b610712565b6040805196875260208701959095529385019290925260608401526001600160a01b0390811660808401521660a082015260c0016101a1565b34801561026257600080fd5b5061018d7f000000000000000000000000e84251b93d9524e0d2e621ba7dc7cb3579f997c081565b34801561029657600080fd5b5061018d7f0000000000000000000000003d32e8b97ed5881324241cf03b2da5e2ebce552181565b3480156102ca57600080fd5b506101576102d9366004611c39565b61077c565b6101576102ec366004611e5a565b6107ca565b3480156102fd57600080fd5b5061015761084d565b34801561031257600080fd5b5061018d7f000000000000000000000000a39739ef8b0231dbfa0dcda07d7e29faabcf4bb281565b34801561034657600080fd5b5061018d7f000000000000000000000000e19968d1cdcf71651a6131b26acc6c23bc12192c81565b34801561037a57600080fd5b5061018d7f0000000000000000000000008fdd3fbfeb32b28fb73555518f8b361bcea741a681565b3480156103ae57600080fd5b506103b7610858565b6040519081526020016101a1565b3480156103d157600080fd5b506103e56103e0366004611ede565b6108a8565b6040805160ff909516855260208501939093529183015260608201526080016101a1565b34801561041557600080fd5b506103b7610424366004611ede565b610978565b34801561043557600080fd5b50610157610444366004611efb565b610a0d565b34801561045557600080fd5b50610157610464366004611c39565b610a6d565b34801561047557600080fd5b50610489610484366004611f46565b610abb565b60408051978852602088019690965294860193909352606085019190915260808401526001600160a01b0390811660a08401521660c082015260e0016101a1565b6101576104d8366004611efb565b610c3e565b3480156104e957600080fd5b506101576104f8366004611c39565b610c98565b34801561050957600080fd5b50610157610518366004611f93565b610cf3565b6001600160a01b03811615610532578061053a565b61053a610d6d565b90506105888134878787873360405160240161055a959493929190612003565b60408051601f198184030181529190526020810180516001600160e01b0316625ba47760e11b1790526110d5565b5050505050565b604051602481018990526001600160a01b03808916604483015280881660648301528616608482015260ff851660a482015260c4810184905260e48101839052336101048201526106129082906000906101240160408051601f198184030181529190526020810180516001600160e01b03166304f1419160e01b1790526110d5565b5050505050505050565b604051602481018b90526001600160a01b03808b166044830152606482018a9052808916608483015280881660a4830152861660c482015260ff851660e482015261010481018490526101248101839052336101448201526106af90829034906101640160408051601f198184030181529190526020810180516001600160e01b0316631751ce6360e01b1790526110d5565b50505050505050505050565b6040516001600160a01b038316602482015233604482015261070e90829060009060640160408051601f198184030181529190526020810180516001600160e01b0316630e39b97960e21b1790526110d5565b5050565b6000680ad78ebc5ac62000008180808061072b886112bd565b9550610740680ad78ebc5ac620000087612047565b9350836107568868056bc75e2d6310000061205f565b6107609190612094565b925061076b83611381565b969995985093965091949293915050565b610588816000878787873360405160240161079b959493929190612003565b60408051601f198184030181529190526020810180516001600160e01b0316635d83dc3960e01b1790526110d5565b6040518815156024820152604481018890526001600160a01b0380881660648301526084820187905280861660a483015280851660c4830152831660e4820152336101048201526106129082903490610124015b60408051601f198184030181529190526020810180516001600160e01b0316636239615d60e01b1790526110d5565b610855610d6d565b50565b600080600061086561156b565b9092509050600061ffff8316610885612710670de0b6b3a7640000612094565b61088f919061205f565b905081811061089e57806108a0565b815b935050505090565b604051630ddec86760e31b81526001600160a01b0382811660048301526000918291829182917f000000000000000000000000a39739ef8b0231dbfa0dcda07d7e29faabcf4bb21690636ef643389060240160a060405180830381865afa158015610917573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093b91906120b6565b50965090945090915050680ad78ebc5ac6200000811161095c57600061096f565b61096f680ad78ebc5ac620000082612114565b91509193509193565b604051639b56d6c960e01b81526001600160a01b0382811660048301526000917f0000000000000000000000003d32e8b97ed5881324241cf03b2da5e2ebce552190911690639b56d6c990602401602060405180830381865afa1580156109e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a07919061212b565b92915050565b6040516001600160a01b03808516602483015283166044820152336064820152610a6890829060009060840160408051601f198184030181529190526020810180516001600160e01b031663c410654b60e01b1790526110d5565b505050565b6105888160008787878733604051602401610a8c959493929190612003565b60408051601f198184030181529190526020810180516001600160e01b0316630c892a6360e41b1790526110d5565b6000806000806000806000680ad78ebc5ac620000094506000807f000000000000000000000000a39739ef8b0231dbfa0dcda07d7e29faabcf4bb26001600160a01b031663b91af97c8b6040518263ffffffff1660e01b8152600401610b3091906001600160a01b0391909116815260200190565b608060405180830381865afa158015610b4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b719190612144565b5050915091506000680ad78ebc5ac620000083610b8e9190612114565b90508c15610ba757610ba08c83612047565b9950610bb4565b610bb18c83612114565b99505b8e15610bd9576000610bc58f6112bd565b9050610bd18183612047565b995050610be6565b610be38e82612114565b98505b610bf9680ad78ebc5ac62000008a612047565b965086610c0f8b68056bc75e2d6310000061205f565b610c199190612094565b9550610c2486611381565b8095508196505050505050959b949a509550955095509550565b6040516001600160a01b03808516602483015283166044820152336064820152610a68908290349060840160408051601f198184030181529190526020810180516001600160e01b0316637055ef3960e11b17905261186c565b60405160016024820152604481018690526001600160a01b0380861660648301526000608483018190523360a4840181905282871660c485015291851660e4840152610104830191909152610588918391906101240161081e565b6040516001600160a01b0380881660248301528616604482015260ff851660648201526084810184905260a481018390523360c4820152610d6590829060009060e40160408051601f198184030181529190526020810180516001600160e01b0316633d482ce960e21b1790526110d5565b505050505050565b6000807f000000000000000000000000a26e15c895efc0616177b7c1e7270a4c7d51c9976001600160a01b0316638e1a55fc6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df4919061217a565b6040516321f8a72160e01b81527f8b16b0b80f67879a61157c5541d94886825d45098bee58e37e2d2e87b2fe367b60048201529091506000906001600160a01b037f000000000000000000000000e19968d1cdcf71651a6131b26acc6c23bc12192c16906321f8a72190602401602060405180830381865afa158015610e7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea2919061217a565b604051637a9e5e4b60e01b81526001600160a01b03808316600483015291925090831690637a9e5e4b90602401600060405180830381600087803b158015610ee957600080fd5b505af1158015610efd573d6000803e3d6000fd5b50506040516313af403560e01b81523360048201526001600160a01b03851692506313af40359150602401600060405180830381600087803b158015610f4257600080fd5b505af1158015610f56573d6000803e3d6000fd5b50506040516001600160a01b03851692503391507f11f81d728010658858b98bd3e5ece1f1a7a9caf6fb57f3742794cfc1c1e8aa9090600090a36040516321f8a72160e01b81527fe02f0ae036ce53d23638e7b8f91c7b58ddb5bb2ac782194ca7ae5ff0826a8c6f60048201526000907f000000000000000000000000e19968d1cdcf71651a6131b26acc6c23bc12192c6001600160a01b0316906321f8a72190602401602060405180830381865afa158015611017573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103b919061217a565b9050806001600160a01b03166385d3a13230338660405160200161106e91906001600160a01b0391909116815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161109b939291906121e4565b600060405180830381600087803b1580156110b557600080fd5b505af11580156110c9573d6000803e3d6000fd5b50949695505050505050565b82336001600160a01b0316816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561111e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611142919061217a565b6001600160a01b03161461119d5760405162461bcd60e51b815260206004820152601c60248201527f53656e6465722068617320746f2062652070726f7879206f776e65720000000060448201526064015b60405180910390fd5b836001600160a01b0316631cff79cd847f000000000000000000000000e19968d1cdcf71651a6131b26acc6c23bc12192c6001600160a01b03166321f8a7217feb35d5f9843d4076628c4747d195abdd0312e0b8b8f5812a706f3d25ea0b10746040518263ffffffff1660e01b815260040161121b91815260200190565b602060405180830381865afa158015611238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125c919061217a565b856040518463ffffffff1660e01b815260040161127a929190612241565b60206040518083038185885af1158015611298573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610588919061212b565b60008060006112ca61156b565b909250905060006112dc858385611992565b60405163477d66cf60e01b8152600481018290529091506000906001600160a01b037f000000000000000000000000a39739ef8b0231dbfa0dcda07d7e29faabcf4bb2169063477d66cf90602401602060405180830381865afa158015611347573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136b919061212b565b90506113778183612047565b9695505050505050565b60008060007f0000000000000000000000008fdd3fbfeb32b28fb73555518f8b361bcea741a66001600160a01b031663de8fa4316040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611408919061212b565b9050600061141582611a80565b61142090600f61205f565b604051633da0dedf60e11b81526004810187905260248101829052634150555360448201529091506000906001600160a01b037f000000000000000000000000e84251b93d9524e0d2e621ba7dc7cb3579f997c01690637b41bdbe90606401606060405180830381865afa15801561149c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c09190612265565b505060405163105a603760e21b8152600481018890526001600160a01b038083166024830181905260448301529192507f0000000000000000000000008fdd3fbfeb32b28fb73555518f8b361bcea741a69091169063416980dc906064016040805180830381865afa15801561153a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155e919061229c565b9097909650945050505050565b6040516321f8a72160e01b81527f4783a7bf568159da8dab9963f361ffb520fa09d911fcf017b1a7273038b176406004820152600090819081906001600160a01b037f000000000000000000000000e19968d1cdcf71651a6131b26acc6c23bc12192c16906321f8a72190602401602060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a919061217a565b6040516bffffffffffffffffffffffff193360601b1660208201529091506000906001600160a01b0383169063597211b090603401604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161168391815260200190565b602060405180830381865afa1580156116a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c491906122cb565b6040516321f8a72160e01b81527f48fd0b937c5f6bca9b37c93d4dfaa4c645a0d160ca5949ee15270fd6936c924b60048201529091506000906001600160a01b037f000000000000000000000000e19968d1cdcf71651a6131b26acc6c23bc12192c16906321f8a72190602401602060405180830381865afa15801561174e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611772919061217a565b90506117df82826001600160a01b03166349208e026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117da91906122cb565b611bfb565b94507f000000000000000000000000a39739ef8b0231dbfa0dcda07d7e29faabcf4bb26001600160a01b03166366ca4a216040518163ffffffff1660e01b8152600401602060405180830381865afa15801561183f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611863919061212b565b93505050509091565b826001600160a01b0316631cff79cd837f000000000000000000000000e19968d1cdcf71651a6131b26acc6c23bc12192c6001600160a01b03166321f8a7217feb35d5f9843d4076628c4747d195abdd0312e0b8b8f5812a706f3d25ea0b10746040518263ffffffff1660e01b81526004016118ea91815260200190565b602060405180830381865afa158015611907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192b919061217a565b846040518463ffffffff1660e01b8152600401611949929190612241565b60206040518083038185885af1158015611967573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061198c919061212b565b50505050565b60008061ffff83166119ae612710670de0b6b3a7640000612094565b6119b8919061205f565b90508381106119c757806119c9565b835b9050600085670de0b6b3a76400006119e1848361205f565b6119eb9190612094565b6119f59190612047565b9050611a0985670de0b6b3a7640000612047565b611a1b82670de0b6b3a764000061205f565b611a259190612094565b925085831015611a775760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f74206d696e74206c657373207468616e207265717565737465642e6044820152606401611194565b50509392505050565b600081611a8f57506000919050565b50600181600160801b8110611aa95760409190911b9060801c5b680100000000000000008110611ac45760209190911b9060401c5b6401000000008110611adb5760109190911b9060201c5b620100008110611af05760089190911b9060101c5b6101008110611b045760049190911b9060081c5b60108110611b175760029190911b9060041c5b60088110611b2757600182901b91505b6001828481611b3857611b3861207e565b048301901c91506001828481611b5057611b5061207e565b048301901c91506001828481611b6857611b6861207e565b048301901c91506001828481611b8057611b8061207e565b048301901c91506001828481611b9857611b9861207e565b048301901c91506001828481611bb057611bb061207e565b048301901c91506001828481611bc857611bc861207e565b048301901c91506000828481611be057611be061207e565b04905080831015611bf15782611bf3565b805b949350505050565b60008261ffff168261ffff1611611c13576000611c1d565b611c1d83836122ef565b9392505050565b6001600160a01b038116811461085557600080fd5b600080600080600060a08688031215611c5157600080fd5b853594506020860135611c6381611c24565b93506040860135611c7381611c24565b92506060860135611c8381611c24565b91506080860135611c9381611c24565b809150509295509295909350565b60ff8116811461085557600080fd5b600080600080600080600080610100898b031215611ccd57600080fd5b883597506020890135611cdf81611c24565b96506040890135611cef81611c24565b95506060890135611cff81611c24565b94506080890135611d0f81611ca1565b935060a0890135925060c0890135915060e0890135611d2d81611c24565b809150509295985092959890939650565b6000806000806000806000806000806101408b8d031215611d5e57600080fd5b8a35995060208b0135611d7081611c24565b985060408b0135975060608b0135611d8781611c24565b965060808b0135611d9781611c24565b955060a08b0135611da781611c24565b945060c08b0135611db781611ca1565b935060e08b013592506101008b013591506101208b0135611dd781611c24565b809150509295989b9194979a5092959850565b60008060408385031215611dfd57600080fd5b8235611e0881611c24565b91506020830135611e1881611c24565b809150509250929050565b60008060408385031215611e3657600080fd5b50508035926020909101359150565b80358015158114611e5557600080fd5b919050565b600080600080600080600080610100898b031215611e7757600080fd5b611e8089611e45565b9750602089013596506040890135611e9781611c24565b9550606089013594506080890135611eae81611c24565b935060a0890135611ebe81611c24565b925060c0890135611ece81611c24565b915060e0890135611d2d81611c24565b600060208284031215611ef057600080fd5b8135611c1d81611c24565b600080600060608486031215611f1057600080fd5b8335611f1b81611c24565b92506020840135611f2b81611c24565b91506040840135611f3b81611c24565b809150509250925092565b600080600080600060a08688031215611f5e57600080fd5b611f6786611e45565b945060208601359350611f7c60408701611e45565b9250606086013591506080860135611c9381611c24565b60008060008060008060c08789031215611fac57600080fd5b8635611fb781611c24565b95506020870135611fc781611c24565b94506040870135611fd781611ca1565b9350606087013592506080870135915060a0870135611ff581611c24565b809150509295509295509295565b9485526001600160a01b03938416602086015291831660408501528216606084015216608082015260a00190565b634e487b7160e01b600052601160045260246000fd5b6000821982111561205a5761205a612031565b500190565b600081600019048311821515161561207957612079612031565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826120b157634e487b7160e01b600052601260045260246000fd5b500490565b600080600080600060a086880312156120ce57600080fd5b85519450602086015193506040860151925060608601516120ee81611ca1565b60808701519092506fffffffffffffffffffffffffffffffff81168114611c9357600080fd5b60008282101561212657612126612031565b500390565b60006020828403121561213d57600080fd5b5051919050565b6000806000806080858703121561215a57600080fd5b505082516020840151604085015160609095015191969095509092509050565b60006020828403121561218c57600080fd5b8151611c1d81611c24565b6000815180845260005b818110156121bd576020818501810151868301820152016121a1565b818111156121cf576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b038481168252831660208201526080604082018190526010908201526f1bdc195b94db585c9d1058d8dbdd5b9d60821b60a082015260c06060820181905260009061223890830184612197565b95945050505050565b6001600160a01b0383168152604060208201819052600090611bf390830184612197565b60008060006060848603121561227a57600080fd5b835161228581611c24565b602085015160409095015190969495509392505050565b600080604083850312156122af57600080fd5b82516122ba81611c24565b6020840151909250611e1881611c24565b6000602082840312156122dd57600080fd5b815161ffff81168114611c1d57600080fd5b600061ffff8381169083168181101561230a5761230a612031565b03939250505056fea264697066735822122078bddd6ceaf72b058d267ba845ccbd54b29f21e9ce281a28c452f5ec59b71bed64736f6c634300080a0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000e19968d1cdcf71651a6131b26acc6c23bc12192c000000000000000000000000a39739ef8b0231dbfa0dcda07d7e29faabcf4bb2000000000000000000000000e84251b93d9524e0d2e621ba7dc7cb3579f997c00000000000000000000000008fdd3fbfeb32b28fb73555518f8b361bcea741a60000000000000000000000003d32e8b97ed5881324241cf03b2da5e2ebce5521000000000000000000000000a26e15c895efc0616177b7c1e7270a4c7d51c997

-----Decoded View---------------
Arg [0] : _registry (address): 0xe19968D1CDcF71651A6131B26ACC6c23bC12192C
Arg [1] : _troveManager (address): 0xA39739EF8b0231DbFA0DcdA07d7e29faAbCf4bb2
Arg [2] : _hintHelpers (address): 0xE84251b93D9524E0d2e621Ba7dc7cb3579F997C0
Arg [3] : _sortedTroves (address): 0x8FdD3fbFEb32b28fb73555518f8b361bCeA741A6
Arg [4] : _collSurplusPool (address): 0x3D32e8b97Ed5881324241Cf03b2DA5E2EBcE5521
Arg [5] : _proxyFactory (address): 0xA26e15C895EFc0616177B7c1e7270A4C7D51C997

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000e19968d1cdcf71651a6131b26acc6c23bc12192c
Arg [1] : 000000000000000000000000a39739ef8b0231dbfa0dcda07d7e29faabcf4bb2
Arg [2] : 000000000000000000000000e84251b93d9524e0d2e621ba7dc7cb3579f997c0
Arg [3] : 0000000000000000000000008fdd3fbfeb32b28fb73555518f8b361bcea741a6
Arg [4] : 0000000000000000000000003d32e8b97ed5881324241cf03b2da5e2ebce5521
Arg [5] : 000000000000000000000000a26e15c895efc0616177b7c1e7270a4c7d51c997


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.