Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
LiquityClaim
Compiler Version
v0.8.10+commit.fc410830
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-02-13 */ // SPDX-License-Identifier: MIT pragma solidity =0.8.10; pragma experimental ABIEncoderV2; interface IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint256 digits); function totalSupply() external view returns (uint256 supply); function balanceOf(address _owner) external view returns (uint256 balance); function transfer(address _to, uint256 _value) external returns (bool success); function transferFrom( address _from, address _to, uint256 _value ) external returns (bool success); function approve(address _spender, uint256 _value) external returns (bool success); function allowance(address _owner, address _spender) external view returns (uint256 remaining); event Approval(address indexed _owner, address indexed _spender, uint256 _value); } abstract contract IWETH { function allowance(address, address) public virtual view returns (uint256); function balanceOf(address) public virtual view returns (uint256); function approve(address, uint256) public virtual; function transfer(address, uint256) public virtual returns (bool); function transferFrom( address, address, uint256 ) public virtual returns (bool); function deposit() public payable virtual; function withdraw(uint256) public virtual; } library Address { //insufficient balance error InsufficientBalance(uint256 available, uint256 required); //unable to send value, recipient may have reverted error SendingValueFail(); //insufficient balance for call error InsufficientBalanceForCall(uint256 available, uint256 required); //call to non-contract error NonContractCall(); function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } function sendValue(address payable recipient, uint256 amount) internal { uint256 balance = address(this).balance; if (balance < amount){ revert InsufficientBalance(balance, amount); } // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{value: amount}(""); if (!(success)){ revert SendingValueFail(); } } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { uint256 balance = address(this).balance; if (balance < value){ revert InsufficientBalanceForCall(balance, value); } return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue( address target, bytes memory data, uint256 weiValue, string memory errorMessage ) private returns (bytes memory) { if (!(isContract(target))){ revert NonContractCall(); } // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{value: weiValue}(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /// @dev Edited so it always first approves 0 and then the value, because of non standard tokens function safeApprove( IERC20 token, address spender, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance) ); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).sub( value, "SafeERC20: decreased allowance below zero" ); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance) ); } function _callOptionalReturn(IERC20 token, bytes memory data) private { bytes memory returndata = address(token).functionCall( data, "SafeERC20: low-level call failed" ); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } library TokenUtils { using SafeERC20 for IERC20; address public constant WETH_ADDR = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address public constant ETH_ADDR = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; function approveToken( address _tokenAddr, address _to, uint256 _amount ) internal { if (_tokenAddr == ETH_ADDR) return; if (IERC20(_tokenAddr).allowance(address(this), _to) < _amount) { IERC20(_tokenAddr).safeApprove(_to, _amount); } } function pullTokensIfNeeded( address _token, address _from, uint256 _amount ) internal returns (uint256) { // handle max uint amount if (_amount == type(uint256).max) { _amount = getBalance(_token, _from); } if (_from != address(0) && _from != address(this) && _token != ETH_ADDR && _amount != 0) { IERC20(_token).safeTransferFrom(_from, address(this), _amount); } return _amount; } function withdrawTokens( address _token, address _to, uint256 _amount ) internal returns (uint256) { if (_amount == type(uint256).max) { _amount = getBalance(_token, address(this)); } if (_to != address(0) && _to != address(this) && _amount != 0) { if (_token != ETH_ADDR) { IERC20(_token).safeTransfer(_to, _amount); } else { payable(_to).transfer(_amount); } } return _amount; } function depositWeth(uint256 _amount) internal { IWETH(WETH_ADDR).deposit{value: _amount}(); } function withdrawWeth(uint256 _amount) internal { IWETH(WETH_ADDR).withdraw(_amount); } function getBalance(address _tokenAddr, address _acc) internal view returns (uint256) { if (_tokenAddr == ETH_ADDR) { return _acc.balance; } else { return IERC20(_tokenAddr).balanceOf(_acc); } } function getTokenDecimals(address _token) internal view returns (uint256) { if (_token == ETH_ADDR) return 18; return IERC20(_token).decimals(); } } 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); } interface IBorrowerOperations { // --- Events --- event TroveManagerAddressChanged(address _newTroveManagerAddress); event ActivePoolAddressChanged(address _activePoolAddress); event DefaultPoolAddressChanged(address _defaultPoolAddress); event StabilityPoolAddressChanged(address _stabilityPoolAddress); event GasPoolAddressChanged(address _gasPoolAddress); event CollSurplusPoolAddressChanged(address _collSurplusPoolAddress); event PriceFeedAddressChanged(address _newPriceFeedAddress); event SortedTrovesAddressChanged(address _sortedTrovesAddress); event LUSDTokenAddressChanged(address _lusdTokenAddress); event LQTYStakingAddressChanged(address _lqtyStakingAddress); event TroveCreated(address indexed _borrower, uint arrayIndex); event TroveUpdated(address indexed _borrower, uint _debt, uint _coll, uint stake, uint8 operation); event LUSDBorrowingFeePaid(address indexed _borrower, uint _LUSDFee); // --- Functions --- function openTrove(uint _maxFee, uint _LUSDAmount, address _upperHint, address _lowerHint) external payable; function addColl(address _upperHint, address _lowerHint) external payable; function moveETHGainToTrove(address _user, address _upperHint, address _lowerHint) external payable; function withdrawColl(uint _amount, address _upperHint, address _lowerHint) external; function withdrawLUSD(uint _maxFee, uint _amount, address _upperHint, address _lowerHint) external; function repayLUSD(uint _amount, address _upperHint, address _lowerHint) external; function closeTrove() external; function adjustTrove(uint _maxFee, uint _collWithdrawal, uint _debtChange, bool isDebtIncrease, address _upperHint, address _lowerHint) external payable; function claimCollateral() external; function getCompositeDebt(uint _debt) external pure returns (uint); } interface IPriceFeed { function lastGoodPrice() external pure returns (uint256); function fetchPrice() external returns (uint); } 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); } 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); } 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; } interface IStabilityPool { // --- Events --- event StabilityPoolETHBalanceUpdated(uint _newBalance); event StabilityPoolLUSDBalanceUpdated(uint _newBalance); event BorrowerOperationsAddressChanged(address _newBorrowerOperationsAddress); event TroveManagerAddressChanged(address _newTroveManagerAddress); event ActivePoolAddressChanged(address _newActivePoolAddress); event DefaultPoolAddressChanged(address _newDefaultPoolAddress); event LUSDTokenAddressChanged(address _newLUSDTokenAddress); event SortedTrovesAddressChanged(address _newSortedTrovesAddress); event PriceFeedAddressChanged(address _newPriceFeedAddress); event CommunityIssuanceAddressChanged(address _newCommunityIssuanceAddress); event P_Updated(uint _P); event S_Updated(uint _S, uint128 _epoch, uint128 _scale); event G_Updated(uint _G, uint128 _epoch, uint128 _scale); event EpochUpdated(uint128 _currentEpoch); event ScaleUpdated(uint128 _currentScale); event FrontEndRegistered(address indexed _frontEnd, uint _kickbackRate); event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd); event DepositSnapshotUpdated(address indexed _depositor, uint _P, uint _S, uint _G); event FrontEndSnapshotUpdated(address indexed _frontEnd, uint _P, uint _G); event UserDepositChanged(address indexed _depositor, uint _newDeposit); event FrontEndStakeChanged(address indexed _frontEnd, uint _newFrontEndStake, address _depositor); event ETHGainWithdrawn(address indexed _depositor, uint _ETH, uint _LUSDLoss); event LQTYPaidToDepositor(address indexed _depositor, uint _LQTY); event LQTYPaidToFrontEnd(address indexed _frontEnd, uint _LQTY); event EtherSent(address _to, uint _amount); // --- Functions --- /* * Called only once on init, to set addresses of other Liquity contracts * Callable only by owner, renounces ownership at the end */ function setAddresses( address _borrowerOperationsAddress, address _troveManagerAddress, address _activePoolAddress, address _lusdTokenAddress, address _sortedTrovesAddress, address _priceFeedAddress, address _communityIssuanceAddress ) external; /* * Initial checks: * - Frontend is registered or zero address * - Sender is not a registered frontend * - _amount is not zero * --- * - Triggers a LQTY issuance, based on time passed since the last issuance. The LQTY issuance is shared between *all* depositors and front ends * - Tags the deposit with the provided front end tag param, if it's a new deposit * - Sends depositor's accumulated gains (LQTY, ETH) to depositor * - Sends the tagged front end's accumulated LQTY gains to the tagged front end * - Increases deposit and tagged front end's stake, and takes new snapshots for each. */ function provideToSP(uint _amount, address _frontEndTag) external; /* * Initial checks: * - _amount is zero or there are no under collateralized troves left in the system * - User has a non zero deposit * --- * - Triggers a LQTY issuance, based on time passed since the last issuance. The LQTY issuance is shared between *all* depositors and front ends * - Removes the deposit's front end tag if it is a full withdrawal * - Sends all depositor's accumulated gains (LQTY, ETH) to depositor * - Sends the tagged front end's accumulated LQTY gains to the tagged front end * - Decreases deposit and tagged front end's stake, and takes new snapshots for each. * * If _amount > userDeposit, the user withdraws all of their compounded deposit. */ function withdrawFromSP(uint _amount) external; /* * Initial checks: * - User has a non zero deposit * - User has an open trove * - User has some ETH gain * --- * - Triggers a LQTY issuance, based on time passed since the last issuance. The LQTY issuance is shared between *all* depositors and front ends * - Sends all depositor's LQTY gain to depositor * - Sends all tagged front end's LQTY gain to the tagged front end * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove * - Leaves their compounded deposit in the Stability Pool * - Updates snapshots for deposit and tagged front end stake */ function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external; /* * Initial checks: * - Frontend (sender) not already registered * - User (sender) has no deposit * - _kickbackRate is in the range [0, 100%] * --- * Front end makes a one-time selection of kickback rate upon registering */ function registerFrontEnd(uint _kickbackRate) external; /* * Initial checks: * - Caller is TroveManager * --- * Cancels out the specified debt against the LUSD contained in the Stability Pool (as far as possible) * and transfers the Trove's ETH collateral from ActivePool to StabilityPool. * Only called by liquidation functions in the TroveManager. */ function offset(uint _debt, uint _coll) external; /* * Returns the total amount of ETH held by the pool, accounted in an internal variable instead of `balance`, * to exclude edge cases like ETH received from a self-destruct. */ function getETH() external view returns (uint); /* * Returns LUSD held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset. */ function getTotalLUSDDeposits() external view returns (uint); /* * Calculates the ETH gain earned by the deposit since its last snapshots were taken. */ function getDepositorETHGain(address _depositor) external view returns (uint); /* * Calculate the LQTY gain earned by a deposit since its last snapshots were taken. * If not tagged with a front end, the depositor gets a 100% cut of what their deposit earned. * Otherwise, their cut of the deposit's earnings is equal to the kickbackRate, set by the front end through * which they made their deposit. */ function getDepositorLQTYGain(address _depositor) external view returns (uint); /* * Return the LQTY gain earned by the front end. */ function getFrontEndLQTYGain(address _frontEnd) external view returns (uint); /* * Return the user's compounded deposit. */ function getCompoundedLUSDDeposit(address _depositor) external view returns (uint); /* * Return the front end's compounded stake. * * The front end's compounded stake is equal to the sum of its depositors' compounded deposits. */ function getCompoundedFrontEndStake(address _frontEnd) external view returns (uint); } interface ILQTYStaking { // --- Events -- event LQTYTokenAddressSet(address _lqtyTokenAddress); event LUSDTokenAddressSet(address _lusdTokenAddress); event TroveManagerAddressSet(address _troveManager); event BorrowerOperationsAddressSet(address _borrowerOperationsAddress); event ActivePoolAddressSet(address _activePoolAddress); event StakeChanged(address indexed staker, uint newStake); event StakingGainsWithdrawn(address indexed staker, uint LUSDGain, uint ETHGain); event F_ETHUpdated(uint _F_ETH); event F_LUSDUpdated(uint _F_LUSD); event TotalLQTYStakedUpdated(uint _totalLQTYStaked); event EtherSent(address _account, uint _amount); event StakerSnapshotsUpdated(address _staker, uint _F_ETH, uint _F_LUSD); // --- Functions --- function setAddresses ( address _lqtyTokenAddress, address _lusdTokenAddress, address _troveManagerAddress, address _borrowerOperationsAddress, address _activePoolAddress ) external; function stake(uint _LQTYamount) external; function unstake(uint _LQTYamount) external; function increaseF_ETH(uint _ETHFee) external; function increaseF_LUSD(uint _LQTYFee) external; function getPendingETHGain(address _user) external view returns (uint); function getPendingLUSDGain(address _user) external view returns (uint); function stakes(address) external view returns (uint256); } contract MainnetLiquityAddresses { address internal constant LUSD_TOKEN_ADDRESS = 0x5f98805A4E8be255a32880FDeC7F6728C6568bA0; address internal constant LQTY_TOKEN_ADDRESS = 0x6DEA81C8171D0bA574754EF6F8b412F2Ed88c54D; address internal constant PRICE_FEED_ADDRESS = 0x4c517D4e2C851CA76d7eC94B805269Df0f2201De; address internal constant BORROWER_OPERATIONS_ADDRESS = 0x24179CD81c9e782A4096035f7eC97fB8B783e007; address internal constant TROVE_MANAGER_ADDRESS = 0xA39739EF8b0231DbFA0DcdA07d7e29faAbCf4bb2; address internal constant SORTED_TROVES_ADDRESS = 0x8FdD3fbFEb32b28fb73555518f8b361bCeA741A6; address internal constant HINT_HELPERS_ADDRESS = 0xE84251b93D9524E0d2e621Ba7dc7cb3579F997C0; address internal constant COLL_SURPLUS_POOL_ADDRESS = 0x3D32e8b97Ed5881324241Cf03b2DA5E2EBcE5521; address internal constant STABILITY_POOL_ADDRESS = 0x66017D22b0f8556afDd19FC67041899Eb65a21bb; address internal constant LQTY_STAKING_ADDRESS = 0x4f9Fbb3f1E99B56e0Fe2892e623Ed36A76Fc605d; address internal constant LQTY_FRONT_END_ADDRESS = 0x76720aC2574631530eC8163e4085d6F98513fb27; } contract LiquityHelper is MainnetLiquityAddresses { using TokenUtils for address; uint constant public LUSD_GAS_COMPENSATION = 200e18; IPriceFeed constant public PriceFeed = IPriceFeed(PRICE_FEED_ADDRESS); IBorrowerOperations constant public BorrowerOperations = IBorrowerOperations(BORROWER_OPERATIONS_ADDRESS); ITroveManager constant public TroveManager = ITroveManager(TROVE_MANAGER_ADDRESS); ISortedTroves constant public SortedTroves = ISortedTroves(SORTED_TROVES_ADDRESS); IHintHelpers constant public HintHelpers = IHintHelpers(HINT_HELPERS_ADDRESS); ICollSurplusPool constant public CollSurplusPool = ICollSurplusPool(COLL_SURPLUS_POOL_ADDRESS); IStabilityPool constant public StabilityPool = IStabilityPool(STABILITY_POOL_ADDRESS); ILQTYStaking constant public LQTYStaking = ILQTYStaking(LQTY_STAKING_ADDRESS); function withdrawStaking(uint256 _ethGain, uint256 _lusdGain, address _wethTo, address _lusdTo) internal { if (_ethGain > 0) { TokenUtils.depositWeth(_ethGain); TokenUtils.WETH_ADDR.withdrawTokens(_wethTo, _ethGain); } if (_lusdGain > 0) { LUSD_TOKEN_ADDRESS.withdrawTokens(_lusdTo, _lusdGain); } } function withdrawStabilityGains(uint256 _ethGain, uint256 _lqtyGain, address _wethTo, address _lqtyTo) internal { if (_ethGain > 0) { TokenUtils.depositWeth(_ethGain); TokenUtils.WETH_ADDR.withdrawTokens(_wethTo, _ethGain); } if (_lqtyGain > 0) { LQTY_TOKEN_ADDRESS.withdrawTokens(_lqtyTo, _lqtyGain); } } } abstract contract IDFSRegistry { function getAddr(bytes4 _id) public view virtual returns (address); function addNewContract( bytes32 _id, address _contractAddr, uint256 _waitPeriod ) public virtual; function startContractChange(bytes32 _id, address _newContractAddr) public virtual; function approveContractChange(bytes32 _id) public virtual; function cancelContractChange(bytes32 _id) public virtual; function changeWaitPeriod(bytes32 _id, uint256 _newWaitPeriod) public virtual; } contract MainnetAuthAddresses { address internal constant ADMIN_VAULT_ADDR = 0xCCf3d848e08b94478Ed8f46fFead3008faF581fD; address internal constant FACTORY_ADDRESS = 0x5a15566417e6C1c9546523066500bDDBc53F88C7; address internal constant ADMIN_ADDR = 0x25eFA336886C74eA8E282ac466BdCd0199f85BB9; // USED IN ADMIN VAULT CONSTRUCTOR } contract AuthHelper is MainnetAuthAddresses { } contract AdminVault is AuthHelper { address public owner; address public admin; error SenderNotAdmin(); constructor() { owner = msg.sender; admin = ADMIN_ADDR; } /// @notice Admin is able to change owner /// @param _owner Address of new owner function changeOwner(address _owner) public { if (admin != msg.sender){ revert SenderNotAdmin(); } owner = _owner; } /// @notice Admin is able to set new admin /// @param _admin Address of multisig that becomes new admin function changeAdmin(address _admin) public { if (admin != msg.sender){ revert SenderNotAdmin(); } admin = _admin; } } contract AdminAuth is AuthHelper { using SafeERC20 for IERC20; AdminVault public constant adminVault = AdminVault(ADMIN_VAULT_ADDR); error SenderNotOwner(); error SenderNotAdmin(); modifier onlyOwner() { if (adminVault.owner() != msg.sender){ revert SenderNotOwner(); } _; } modifier onlyAdmin() { if (adminVault.admin() != msg.sender){ revert SenderNotAdmin(); } _; } /// @notice withdraw stuck funds function withdrawStuckFunds(address _token, address _receiver, uint256 _amount) public onlyOwner { if (_token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) { payable(_receiver).transfer(_amount); } else { IERC20(_token).safeTransfer(_receiver, _amount); } } /// @notice Destroy the contract function kill() public onlyAdmin { selfdestruct(payable(msg.sender)); } } contract DFSRegistry is AdminAuth { error EntryAlreadyExistsError(bytes4); error EntryNonExistentError(bytes4); error EntryNotInChangeError(bytes4); error ChangeNotReadyError(uint256,uint256); error EmptyPrevAddrError(bytes4); error AlreadyInContractChangeError(bytes4); error AlreadyInWaitPeriodChangeError(bytes4); event AddNewContract(address,bytes4,address,uint256); event RevertToPreviousAddress(address,bytes4,address,address); event StartContractChange(address,bytes4,address,address); event ApproveContractChange(address,bytes4,address,address); event CancelContractChange(address,bytes4,address,address); event StartWaitPeriodChange(address,bytes4,uint256); event ApproveWaitPeriodChange(address,bytes4,uint256,uint256); event CancelWaitPeriodChange(address,bytes4,uint256,uint256); struct Entry { address contractAddr; uint256 waitPeriod; uint256 changeStartTime; bool inContractChange; bool inWaitPeriodChange; bool exists; } mapping(bytes4 => Entry) public entries; mapping(bytes4 => address) public previousAddresses; mapping(bytes4 => address) public pendingAddresses; mapping(bytes4 => uint256) public pendingWaitTimes; /// @notice Given an contract id returns the registered address /// @dev Id is keccak256 of the contract name /// @param _id Id of contract function getAddr(bytes4 _id) public view returns (address) { return entries[_id].contractAddr; } /// @notice Helper function to easily query if id is registered /// @param _id Id of contract function isRegistered(bytes4 _id) public view returns (bool) { return entries[_id].exists; } /////////////////////////// OWNER ONLY FUNCTIONS /////////////////////////// /// @notice Adds a new contract to the registry /// @param _id Id of contract /// @param _contractAddr Address of the contract /// @param _waitPeriod Amount of time to wait before a contract address can be changed function addNewContract( bytes4 _id, address _contractAddr, uint256 _waitPeriod ) public onlyOwner { if (entries[_id].exists){ revert EntryAlreadyExistsError(_id); } entries[_id] = Entry({ contractAddr: _contractAddr, waitPeriod: _waitPeriod, changeStartTime: 0, inContractChange: false, inWaitPeriodChange: false, exists: true }); emit AddNewContract(msg.sender, _id, _contractAddr, _waitPeriod); } /// @notice Reverts to the previous address immediately /// @dev In case the new version has a fault, a quick way to fallback to the old contract /// @param _id Id of contract function revertToPreviousAddress(bytes4 _id) public onlyOwner { if (!(entries[_id].exists)){ revert EntryNonExistentError(_id); } if (previousAddresses[_id] == address(0)){ revert EmptyPrevAddrError(_id); } address currentAddr = entries[_id].contractAddr; entries[_id].contractAddr = previousAddresses[_id]; emit RevertToPreviousAddress(msg.sender, _id, currentAddr, previousAddresses[_id]); } /// @notice Starts an address change for an existing entry /// @dev Can override a change that is currently in progress /// @param _id Id of contract /// @param _newContractAddr Address of the new contract function startContractChange(bytes4 _id, address _newContractAddr) public onlyOwner { if (!entries[_id].exists){ revert EntryNonExistentError(_id); } if (entries[_id].inWaitPeriodChange){ revert AlreadyInWaitPeriodChangeError(_id); } entries[_id].changeStartTime = block.timestamp; // solhint-disable-line entries[_id].inContractChange = true; pendingAddresses[_id] = _newContractAddr; emit StartContractChange(msg.sender, _id, entries[_id].contractAddr, _newContractAddr); } /// @notice Changes new contract address, correct time must have passed /// @param _id Id of contract function approveContractChange(bytes4 _id) public onlyOwner { if (!entries[_id].exists){ revert EntryNonExistentError(_id); } if (!entries[_id].inContractChange){ revert EntryNotInChangeError(_id); } if (block.timestamp < (entries[_id].changeStartTime + entries[_id].waitPeriod)){// solhint-disable-line revert ChangeNotReadyError(block.timestamp, (entries[_id].changeStartTime + entries[_id].waitPeriod)); } address oldContractAddr = entries[_id].contractAddr; entries[_id].contractAddr = pendingAddresses[_id]; entries[_id].inContractChange = false; entries[_id].changeStartTime = 0; pendingAddresses[_id] = address(0); previousAddresses[_id] = oldContractAddr; emit ApproveContractChange(msg.sender, _id, oldContractAddr, entries[_id].contractAddr); } /// @notice Cancel pending change /// @param _id Id of contract function cancelContractChange(bytes4 _id) public onlyOwner { if (!entries[_id].exists){ revert EntryNonExistentError(_id); } if (!entries[_id].inContractChange){ revert EntryNotInChangeError(_id); } address oldContractAddr = pendingAddresses[_id]; pendingAddresses[_id] = address(0); entries[_id].inContractChange = false; entries[_id].changeStartTime = 0; emit CancelContractChange(msg.sender, _id, oldContractAddr, entries[_id].contractAddr); } /// @notice Starts the change for waitPeriod /// @param _id Id of contract /// @param _newWaitPeriod New wait time function startWaitPeriodChange(bytes4 _id, uint256 _newWaitPeriod) public onlyOwner { if (!entries[_id].exists){ revert EntryNonExistentError(_id); } if (entries[_id].inContractChange){ revert AlreadyInContractChangeError(_id); } pendingWaitTimes[_id] = _newWaitPeriod; entries[_id].changeStartTime = block.timestamp; // solhint-disable-line entries[_id].inWaitPeriodChange = true; emit StartWaitPeriodChange(msg.sender, _id, _newWaitPeriod); } /// @notice Changes new wait period, correct time must have passed /// @param _id Id of contract function approveWaitPeriodChange(bytes4 _id) public onlyOwner { if (!entries[_id].exists){ revert EntryNonExistentError(_id); } if (!entries[_id].inWaitPeriodChange){ revert EntryNotInChangeError(_id); } if (block.timestamp < (entries[_id].changeStartTime + entries[_id].waitPeriod)){ // solhint-disable-line revert ChangeNotReadyError(block.timestamp, (entries[_id].changeStartTime + entries[_id].waitPeriod)); } uint256 oldWaitTime = entries[_id].waitPeriod; entries[_id].waitPeriod = pendingWaitTimes[_id]; entries[_id].inWaitPeriodChange = false; entries[_id].changeStartTime = 0; pendingWaitTimes[_id] = 0; emit ApproveWaitPeriodChange(msg.sender, _id, oldWaitTime, entries[_id].waitPeriod); } /// @notice Cancel wait period change /// @param _id Id of contract function cancelWaitPeriodChange(bytes4 _id) public onlyOwner { if (!entries[_id].exists){ revert EntryNonExistentError(_id); } if (!entries[_id].inWaitPeriodChange){ revert EntryNotInChangeError(_id); } uint256 oldWaitPeriod = pendingWaitTimes[_id]; pendingWaitTimes[_id] = 0; entries[_id].inWaitPeriodChange = false; entries[_id].changeStartTime = 0; emit CancelWaitPeriodChange(msg.sender, _id, oldWaitPeriod, entries[_id].waitPeriod); } } abstract contract DSAuthority { function canCall( address src, address dst, bytes4 sig ) public view virtual returns (bool); } contract DSAuthEvents { event LogSetAuthority(address indexed authority); event LogSetOwner(address indexed owner); } contract DSAuth is DSAuthEvents { DSAuthority public authority; address public owner; constructor() { owner = msg.sender; emit LogSetOwner(msg.sender); } function setOwner(address owner_) public auth { owner = owner_; emit LogSetOwner(owner); } function setAuthority(DSAuthority authority_) public auth { authority = authority_; emit LogSetAuthority(address(authority)); } modifier auth { require(isAuthorized(msg.sender, msg.sig), "Not authorized"); _; } function isAuthorized(address src, bytes4 sig) internal view returns (bool) { if (src == address(this)) { return true; } else if (src == owner) { return true; } else if (authority == DSAuthority(address(0))) { return false; } else { return authority.canCall(src, address(this), sig); } } } contract DSNote { event LogNote( bytes4 indexed sig, address indexed guy, bytes32 indexed foo, bytes32 indexed bar, uint256 wad, bytes fax ) anonymous; modifier note { bytes32 foo; bytes32 bar; assembly { foo := calldataload(4) bar := calldataload(36) } emit LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data); _; } } abstract contract DSProxy is DSAuth, DSNote { DSProxyCache public cache; // global cache for contracts constructor(address _cacheAddr) { if (!(setCache(_cacheAddr))){ require(isAuthorized(msg.sender, msg.sig), "Not authorized"); } } // 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); } contract DSProxyCache { mapping(bytes32 => address) cache; function read(bytes memory _code) public view returns (address) { bytes32 hash = keccak256(_code); return cache[hash]; } function write(bytes memory _code) public returns (address target) { assembly { target := create(0, add(_code, 0x20), mload(_code)) switch iszero(extcodesize(target)) case 1 { // throw if contract failed to deploy revert(0, 0) } } bytes32 hash = keccak256(_code); cache[hash] = target; } } contract DefisaverLogger { event RecipeEvent( address indexed caller, string indexed logName ); event ActionDirectEvent( address indexed caller, string indexed logName, bytes data ); function logRecipeEvent( string memory _logName ) public { emit RecipeEvent(msg.sender, _logName); } function logActionDirectEvent( string memory _logName, bytes memory _data ) public { emit ActionDirectEvent(msg.sender, _logName, _data); } } contract MainnetActionsUtilAddresses { address internal constant DFS_REG_CONTROLLER_ADDR = 0xF8f8B3C98Cf2E63Df3041b73f80F362a4cf3A576; address internal constant REGISTRY_ADDR = 0x287778F121F134C66212FB16c9b53eC991D32f5b; address internal constant DFS_LOGGER_ADDR = 0xcE7a977Cac4a481bc84AC06b2Da0df614e621cf3; } contract ActionsUtilHelper is MainnetActionsUtilAddresses { } abstract contract ActionBase is AdminAuth, ActionsUtilHelper { event ActionEvent( string indexed logName, bytes data ); DFSRegistry public constant registry = DFSRegistry(REGISTRY_ADDR); DefisaverLogger public constant logger = DefisaverLogger( DFS_LOGGER_ADDR ); //Wrong sub index value error SubIndexValueError(); //Wrong return index value error ReturnIndexValueError(); /// @dev Subscription params index range [128, 255] uint8 public constant SUB_MIN_INDEX_VALUE = 128; uint8 public constant SUB_MAX_INDEX_VALUE = 255; /// @dev Return params index range [1, 127] uint8 public constant RETURN_MIN_INDEX_VALUE = 1; uint8 public constant RETURN_MAX_INDEX_VALUE = 127; /// @dev If the input value should not be replaced uint8 public constant NO_PARAM_MAPPING = 0; /// @dev We need to parse Flash loan actions in a different way enum ActionType { FL_ACTION, STANDARD_ACTION, FEE_ACTION, CHECK_ACTION, CUSTOM_ACTION } /// @notice Parses inputs and runs the implemented action through a proxy /// @dev Is called by the RecipeExecutor chaining actions together /// @param _callData Array of input values each value encoded as bytes /// @param _subData Array of subscribed vales, replaces input values if specified /// @param _paramMapping Array that specifies how return and subscribed values are mapped in input /// @param _returnValues Returns values from actions before, which can be injected in inputs /// @return Returns a bytes32 value through DSProxy, each actions implements what that value is function executeAction( bytes memory _callData, bytes32[] memory _subData, uint8[] memory _paramMapping, bytes32[] memory _returnValues ) public payable virtual returns (bytes32); /// @notice Parses inputs and runs the single implemented action through a proxy /// @dev Used to save gas when executing a single action directly function executeActionDirect(bytes memory _callData) public virtual payable; /// @notice Returns the type of action we are implementing function actionType() public pure virtual returns (uint8); //////////////////////////// HELPER METHODS //////////////////////////// /// @notice Given an uint256 input, injects return/sub values if specified /// @param _param The original input value /// @param _mapType Indicated the type of the input in paramMapping /// @param _subData Array of subscription data we can replace the input value with /// @param _returnValues Array of subscription data we can replace the input value with function _parseParamUint( uint _param, uint8 _mapType, bytes32[] memory _subData, bytes32[] memory _returnValues ) internal pure returns (uint) { if (isReplaceable(_mapType)) { if (isReturnInjection(_mapType)) { _param = uint(_returnValues[getReturnIndex(_mapType)]); } else { _param = uint256(_subData[getSubIndex(_mapType)]); } } return _param; } /// @notice Given an addr input, injects return/sub values if specified /// @param _param The original input value /// @param _mapType Indicated the type of the input in paramMapping /// @param _subData Array of subscription data we can replace the input value with /// @param _returnValues Array of subscription data we can replace the input value with function _parseParamAddr( address _param, uint8 _mapType, bytes32[] memory _subData, bytes32[] memory _returnValues ) internal view returns (address) { if (isReplaceable(_mapType)) { if (isReturnInjection(_mapType)) { _param = address(bytes20((_returnValues[getReturnIndex(_mapType)]))); } else { /// @dev The last two values are specially reserved for proxy addr and owner addr if (_mapType == 254) return address(this); //DSProxy address if (_mapType == 255) return DSProxy(payable(address(this))).owner(); // owner of DSProxy _param = address(uint160(uint256(_subData[getSubIndex(_mapType)]))); } } return _param; } /// @notice Given an bytes32 input, injects return/sub values if specified /// @param _param The original input value /// @param _mapType Indicated the type of the input in paramMapping /// @param _subData Array of subscription data we can replace the input value with /// @param _returnValues Array of subscription data we can replace the input value with function _parseParamABytes32( bytes32 _param, uint8 _mapType, bytes32[] memory _subData, bytes32[] memory _returnValues ) internal pure returns (bytes32) { if (isReplaceable(_mapType)) { if (isReturnInjection(_mapType)) { _param = (_returnValues[getReturnIndex(_mapType)]); } else { _param = _subData[getSubIndex(_mapType)]; } } return _param; } /// @notice Checks if the paramMapping value indicated that we need to inject values /// @param _type Indicated the type of the input function isReplaceable(uint8 _type) internal pure returns (bool) { return _type != NO_PARAM_MAPPING; } /// @notice Checks if the paramMapping value is in the return value range /// @param _type Indicated the type of the input function isReturnInjection(uint8 _type) internal pure returns (bool) { return (_type >= RETURN_MIN_INDEX_VALUE) && (_type <= RETURN_MAX_INDEX_VALUE); } /// @notice Transforms the paramMapping value to the index in return array value /// @param _type Indicated the type of the input function getReturnIndex(uint8 _type) internal pure returns (uint8) { if (!(isReturnInjection(_type))){ revert SubIndexValueError(); } return (_type - RETURN_MIN_INDEX_VALUE); } /// @notice Transforms the paramMapping value to the index in sub array value /// @param _type Indicated the type of the input function getSubIndex(uint8 _type) internal pure returns (uint8) { if (_type < SUB_MIN_INDEX_VALUE){ revert ReturnIndexValueError(); } return (_type - SUB_MIN_INDEX_VALUE); } } contract LiquityClaim is ActionBase, LiquityHelper { using TokenUtils for address; /// @inheritdoc ActionBase function executeAction( bytes memory _callData, bytes32[] memory _subData, uint8[] memory _paramMapping, bytes32[] memory _returnValues ) public payable virtual override returns (bytes32) { address to = parseInputs(_callData); to = _parseParamAddr(to, _paramMapping[0], _subData, _returnValues); (uint256 claimedColl, bytes memory logData) = _liquityClaim(to); emit ActionEvent("LiquityClaim", logData); return bytes32(claimedColl); } /// @inheritdoc ActionBase function executeActionDirect(bytes memory _callData) public payable virtual override { address to = parseInputs(_callData); (, bytes memory logData) = _liquityClaim(to); logger.logActionDirectEvent("LiquityClaim", logData); } /// @inheritdoc ActionBase function actionType() public pure virtual override returns (uint8) { return uint8(ActionType.STANDARD_ACTION); } //////////////////////////// ACTION LOGIC //////////////////////////// /// @notice Claims remaining collateral from the user's closed Trove function _liquityClaim(address _to) internal returns (uint256 claimableColl, bytes memory logData) { claimableColl = CollSurplusPool.getCollateral(address(this)); BorrowerOperations.claimCollateral(); // Will revert if claimableColl == 0 TokenUtils.depositWeth(claimableColl); TokenUtils.WETH_ADDR.withdrawTokens(_to, claimableColl); logData = abi.encode(_to, claimableColl); } function parseInputs(bytes memory _callData) internal pure returns (address to) { to = abi.decode(_callData, (address)); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"NonContractCall","type":"error"},{"inputs":[],"name":"ReturnIndexValueError","type":"error"},{"inputs":[],"name":"SenderNotAdmin","type":"error"},{"inputs":[],"name":"SenderNotOwner","type":"error"},{"inputs":[],"name":"SubIndexValueError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"logName","type":"string"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"ActionEvent","type":"event"},{"inputs":[],"name":"BorrowerOperations","outputs":[{"internalType":"contract IBorrowerOperations","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"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":"LQTYStaking","outputs":[{"internalType":"contract ILQTYStaking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LUSD_GAS_COMPENSATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NO_PARAM_MAPPING","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PriceFeed","outputs":[{"internalType":"contract IPriceFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RETURN_MAX_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RETURN_MIN_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUB_MAX_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUB_MIN_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SortedTroves","outputs":[{"internalType":"contract ISortedTroves","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"StabilityPool","outputs":[{"internalType":"contract IStabilityPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TroveManager","outputs":[{"internalType":"contract ITroveManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"actionType","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"adminVault","outputs":[{"internalType":"contract AdminVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"},{"internalType":"bytes32[]","name":"_subData","type":"bytes32[]"},{"internalType":"uint8[]","name":"_paramMapping","type":"uint8[]"},{"internalType":"bytes32[]","name":"_returnValues","type":"bytes32[]"}],"name":"executeAction","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"}],"name":"executeActionDirect","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"kill","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"logger","outputs":[{"internalType":"contract DefisaverLogger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"contract DFSRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawStuckFunds","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061163b806100206000396000f3fe6080604052600436106101755760003560e01c80637b103999116100cb5780639864dcdd1161007f578063d3c2e7ed11610059578063d3c2e7ed1461040e578063f24ccbfe14610423578063f5a8a7fc1461044b57600080fd5b80639864dcdd146103b1578063b15c4000146103c6578063c579d490146103ee57600080fd5b80638cedca71116100b05780638cedca711461034e5780638df50f7414610376578063941990161461038957600080fd5b80637b103999146103115780638bcb62161461033957600080fd5b8063389f87ff1161012d5780635915b3a4116101075780635915b3a41461029957806369a02818146102c15780636ba2ea8f146102e957600080fd5b8063389f87ff1461024757806341c0e1b51461025c5780634acd820e1461027157600080fd5b8063247492f81161015e578063247492f8146101f35780632e86bbd8146102075780632fa13cb81461023257600080fd5b806308b7fa311461017a5780630f2eee42146101cc575b600080fd5b34801561018657600080fd5b506101a2734c517d4e2c851ca76d7ec94b805269df0f2201de81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101d857600080fd5b506101e1608081565b60405160ff90911681526020016101c3565b3480156101ff57600080fd5b5060016101e1565b34801561021357600080fd5b50610224680ad78ebc5ac620000081565b6040519081526020016101c3565b34801561023e57600080fd5b506101e1600081565b61025a61025536600461120e565b610473565b005b34801561026857600080fd5b5061025a610516565b34801561027d57600080fd5b506101a273e84251b93d9524e0d2e621ba7dc7cb3579f997c081565b3480156102a557600080fd5b506101a2733d32e8b97ed5881324241cf03b2da5e2ebce552181565b3480156102cd57600080fd5b506101a273a39739ef8b0231dbfa0dcda07d7e29faabcf4bb281565b3480156102f557600080fd5b506101a27366017d22b0f8556afdd19fc67041899eb65a21bb81565b34801561031d57600080fd5b506101a273287778f121f134c66212fb16c9b53ec991d32f5b81565b34801561034557600080fd5b506101e1600181565b34801561035a57600080fd5b506101a273ccf3d848e08b94478ed8f46ffead3008faf581fd81565b6102246103843660046112d2565b610600565b34801561039557600080fd5b506101a27324179cd81c9e782a4096035f7ec97fb8b783e00781565b3480156103bd57600080fd5b506101e1607f81565b3480156103d257600080fd5b506101a2738fdd3fbfeb32b28fb73555518f8b361bcea741a681565b3480156103fa57600080fd5b5061025a610409366004611407565b6106bc565b34801561041a57600080fd5b506101e160ff81565b34801561042f57600080fd5b506101a273ce7a977cac4a481bc84ac06b2da0df614e621cf381565b34801561045757600080fd5b506101a2734f9fbb3f1e99b56e0fe2892e623ed36a76fc605d81565b600061047e82610844565b9050600061048b82610860565b6040517ff4b24b5500000000000000000000000000000000000000000000000000000000815290925073ce7a977cac4a481bc84ac06b2da0df614e621cf3915063f4b24b55906104df9084906004016114be565b600060405180830381600087803b1580156104f957600080fd5b505af115801561050d573d6000803e3d6000fd5b50505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1673ccf3d848e08b94478ed8f46ffead3008faf581fd73ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa15801561058c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b09190611505565b73ffffffffffffffffffffffffffffffffffffffff16146105fd576040517fa6c827a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33ff5b60008061060c86610844565b9050610634818560008151811061062557610625611522565b602002602001015187866109d0565b905060008061064283610860565b6040517f4c697175697479436c61696d000000000000000000000000000000000000000081529193509150600c0160405180910390207f2b6d22f419271bcc89bbac8deec947c664365d6e24d06fef0ca7c325c704dce3826040516106a79190611551565b60405180910390a2509150505b949350505050565b3373ffffffffffffffffffffffffffffffffffffffff1673ccf3d848e08b94478ed8f46ffead3008faf581fd73ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610732573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107569190611505565b73ffffffffffffffffffffffffffffffffffffffff16146107a3576040517f19494c8a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff8416141561081e5760405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610818573d6000803e3d6000fd5b50505050565b61083f73ffffffffffffffffffffffffffffffffffffffff84168383610ae1565b505050565b60008180602001905181019061085a9190611505565b92915050565b6040517f9b56d6c9000000000000000000000000000000000000000000000000000000008152306004820152600090606090733d32e8b97ed5881324241cf03b2da5e2ebce552190639b56d6c990602401602060405180830381865afa1580156108ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f29190611564565b91507324179cd81c9e782a4096035f7ec97fb8b783e00773ffffffffffffffffffffffffffffffffffffffff16636f0b0c1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561095057600080fd5b505af1158015610964573d6000803e3d6000fd5b5050505061097182610b6e565b61099073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28484610be6565b506040805173ffffffffffffffffffffffffffffffffffffffff851660208201529081018390526060016040516020818303038152906040529050915091565b600060ff841615610ad8576109e484610d0b565b15610a1857816109f385610d2a565b60ff1681518110610a0657610a06611522565b602002602001015160601c9450610ad8565b8360ff1660fe1415610a2b5750306106b4565b8360ff1660ff1415610aad573073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa69190611505565b90506106b4565b82610ab785610d76565b60ff1681518110610aca57610aca611522565b602002602001015160001c94505b50929392505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261083f908490610dc1565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610bca57600080fd5b505af1158015610bde573d6000803e3d6000fd5b505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610c1d57610c1a8430610ed2565b91505b73ffffffffffffffffffffffffffffffffffffffff831615801590610c58575073ffffffffffffffffffffffffffffffffffffffff83163014155b8015610c6357508115155b15610d045773ffffffffffffffffffffffffffffffffffffffff841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14610cbf57610cba73ffffffffffffffffffffffffffffffffffffffff85168484610ae1565b610d04565b60405173ffffffffffffffffffffffffffffffffffffffff84169083156108fc029084906000818181858888f19350505050158015610d02573d6000803e3d6000fd5b505b5092915050565b6000600160ff83161080159061085a5750607f60ff8316111592915050565b6000610d3582610d0b565b610d6b576040517fdcc95a3900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61085a60018361157d565b6000608060ff83161015610db6576040517f866f6e8700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61085a60808361157d565b6000610e23826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610fbb9092919063ffffffff16565b80519091501561083f5780806020019051810190610e4191906115c7565b61083f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610f24575073ffffffffffffffffffffffffffffffffffffffff81163161085a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906370a0823190602401602060405180830381865afa158015610f90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb49190611564565b9392505050565b60606106b484846000856060610fd0856110c9565b611006576040517f304619b500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161102f91906115e9565b60006040518083038185875af1925050503d806000811461106c576040519150601f19603f3d011682016040523d82523d6000602084013e611071565b606091505b509150915081156110855791506106b49050565b8051156110955780518082602001fd5b836040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ec99190611551565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906106b4575050151592915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561117857611178611102565b604052919050565b600082601f83011261119157600080fd5b813567ffffffffffffffff8111156111ab576111ab611102565b6111dc60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611131565b8181528460208386010111156111f157600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561122057600080fd5b813567ffffffffffffffff81111561123757600080fd5b6106b484828501611180565b600067ffffffffffffffff82111561125d5761125d611102565b5060051b60200190565b600082601f83011261127857600080fd5b8135602061128d61128883611243565b611131565b82815260059290921b840181019181810190868411156112ac57600080fd5b8286015b848110156112c757803583529183019183016112b0565b509695505050505050565b600080600080608085870312156112e857600080fd5b843567ffffffffffffffff8082111561130057600080fd5b61130c88838901611180565b955060209150818701358181111561132357600080fd5b61132f89828a01611267565b95505060408701358181111561134457600080fd5b8701601f8101891361135557600080fd5b803561136361128882611243565b81815260059190911b8201840190848101908b83111561138257600080fd5b928501925b828410156113b057833560ff811681146113a15760008081fd5b82529285019290850190611387565b965050505060608701359150808211156113c957600080fd5b506113d687828801611267565b91505092959194509250565b73ffffffffffffffffffffffffffffffffffffffff8116811461140457600080fd5b50565b60008060006060848603121561141c57600080fd5b8335611427816113e2565b92506020840135611437816113e2565b929592945050506040919091013590565b60005b8381101561146357818101518382015260200161144b565b838111156108185750506000910152565b6000815180845261148c816020860160208601611448565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60408152600c60408201527f4c697175697479436c61696d00000000000000000000000000000000000000006060820152608060208201526000610fb46080830184611474565b60006020828403121561151757600080fd5b8151610fb4816113e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602081526000610fb46020830184611474565b60006020828403121561157657600080fd5b5051919050565b600060ff821660ff8416808210156115be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b90039392505050565b6000602082840312156115d957600080fd5b81518015158114610fb457600080fd5b600082516115fb818460208701611448565b919091019291505056fea2646970667358221220a6ed3c5b192eb74ca2df341dd847ac461df995269d35797cb9377d556391215d64736f6c634300080a0033
Deployed Bytecode
0x6080604052600436106101755760003560e01c80637b103999116100cb5780639864dcdd1161007f578063d3c2e7ed11610059578063d3c2e7ed1461040e578063f24ccbfe14610423578063f5a8a7fc1461044b57600080fd5b80639864dcdd146103b1578063b15c4000146103c6578063c579d490146103ee57600080fd5b80638cedca71116100b05780638cedca711461034e5780638df50f7414610376578063941990161461038957600080fd5b80637b103999146103115780638bcb62161461033957600080fd5b8063389f87ff1161012d5780635915b3a4116101075780635915b3a41461029957806369a02818146102c15780636ba2ea8f146102e957600080fd5b8063389f87ff1461024757806341c0e1b51461025c5780634acd820e1461027157600080fd5b8063247492f81161015e578063247492f8146101f35780632e86bbd8146102075780632fa13cb81461023257600080fd5b806308b7fa311461017a5780630f2eee42146101cc575b600080fd5b34801561018657600080fd5b506101a2734c517d4e2c851ca76d7ec94b805269df0f2201de81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101d857600080fd5b506101e1608081565b60405160ff90911681526020016101c3565b3480156101ff57600080fd5b5060016101e1565b34801561021357600080fd5b50610224680ad78ebc5ac620000081565b6040519081526020016101c3565b34801561023e57600080fd5b506101e1600081565b61025a61025536600461120e565b610473565b005b34801561026857600080fd5b5061025a610516565b34801561027d57600080fd5b506101a273e84251b93d9524e0d2e621ba7dc7cb3579f997c081565b3480156102a557600080fd5b506101a2733d32e8b97ed5881324241cf03b2da5e2ebce552181565b3480156102cd57600080fd5b506101a273a39739ef8b0231dbfa0dcda07d7e29faabcf4bb281565b3480156102f557600080fd5b506101a27366017d22b0f8556afdd19fc67041899eb65a21bb81565b34801561031d57600080fd5b506101a273287778f121f134c66212fb16c9b53ec991d32f5b81565b34801561034557600080fd5b506101e1600181565b34801561035a57600080fd5b506101a273ccf3d848e08b94478ed8f46ffead3008faf581fd81565b6102246103843660046112d2565b610600565b34801561039557600080fd5b506101a27324179cd81c9e782a4096035f7ec97fb8b783e00781565b3480156103bd57600080fd5b506101e1607f81565b3480156103d257600080fd5b506101a2738fdd3fbfeb32b28fb73555518f8b361bcea741a681565b3480156103fa57600080fd5b5061025a610409366004611407565b6106bc565b34801561041a57600080fd5b506101e160ff81565b34801561042f57600080fd5b506101a273ce7a977cac4a481bc84ac06b2da0df614e621cf381565b34801561045757600080fd5b506101a2734f9fbb3f1e99b56e0fe2892e623ed36a76fc605d81565b600061047e82610844565b9050600061048b82610860565b6040517ff4b24b5500000000000000000000000000000000000000000000000000000000815290925073ce7a977cac4a481bc84ac06b2da0df614e621cf3915063f4b24b55906104df9084906004016114be565b600060405180830381600087803b1580156104f957600080fd5b505af115801561050d573d6000803e3d6000fd5b50505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1673ccf3d848e08b94478ed8f46ffead3008faf581fd73ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa15801561058c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b09190611505565b73ffffffffffffffffffffffffffffffffffffffff16146105fd576040517fa6c827a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33ff5b60008061060c86610844565b9050610634818560008151811061062557610625611522565b602002602001015187866109d0565b905060008061064283610860565b6040517f4c697175697479436c61696d000000000000000000000000000000000000000081529193509150600c0160405180910390207f2b6d22f419271bcc89bbac8deec947c664365d6e24d06fef0ca7c325c704dce3826040516106a79190611551565b60405180910390a2509150505b949350505050565b3373ffffffffffffffffffffffffffffffffffffffff1673ccf3d848e08b94478ed8f46ffead3008faf581fd73ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610732573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107569190611505565b73ffffffffffffffffffffffffffffffffffffffff16146107a3576040517f19494c8a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff8416141561081e5760405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610818573d6000803e3d6000fd5b50505050565b61083f73ffffffffffffffffffffffffffffffffffffffff84168383610ae1565b505050565b60008180602001905181019061085a9190611505565b92915050565b6040517f9b56d6c9000000000000000000000000000000000000000000000000000000008152306004820152600090606090733d32e8b97ed5881324241cf03b2da5e2ebce552190639b56d6c990602401602060405180830381865afa1580156108ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f29190611564565b91507324179cd81c9e782a4096035f7ec97fb8b783e00773ffffffffffffffffffffffffffffffffffffffff16636f0b0c1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561095057600080fd5b505af1158015610964573d6000803e3d6000fd5b5050505061097182610b6e565b61099073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28484610be6565b506040805173ffffffffffffffffffffffffffffffffffffffff851660208201529081018390526060016040516020818303038152906040529050915091565b600060ff841615610ad8576109e484610d0b565b15610a1857816109f385610d2a565b60ff1681518110610a0657610a06611522565b602002602001015160601c9450610ad8565b8360ff1660fe1415610a2b5750306106b4565b8360ff1660ff1415610aad573073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa69190611505565b90506106b4565b82610ab785610d76565b60ff1681518110610aca57610aca611522565b602002602001015160001c94505b50929392505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261083f908490610dc1565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610bca57600080fd5b505af1158015610bde573d6000803e3d6000fd5b505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610c1d57610c1a8430610ed2565b91505b73ffffffffffffffffffffffffffffffffffffffff831615801590610c58575073ffffffffffffffffffffffffffffffffffffffff83163014155b8015610c6357508115155b15610d045773ffffffffffffffffffffffffffffffffffffffff841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14610cbf57610cba73ffffffffffffffffffffffffffffffffffffffff85168484610ae1565b610d04565b60405173ffffffffffffffffffffffffffffffffffffffff84169083156108fc029084906000818181858888f19350505050158015610d02573d6000803e3d6000fd5b505b5092915050565b6000600160ff83161080159061085a5750607f60ff8316111592915050565b6000610d3582610d0b565b610d6b576040517fdcc95a3900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61085a60018361157d565b6000608060ff83161015610db6576040517f866f6e8700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61085a60808361157d565b6000610e23826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610fbb9092919063ffffffff16565b80519091501561083f5780806020019051810190610e4191906115c7565b61083f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610f24575073ffffffffffffffffffffffffffffffffffffffff81163161085a565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906370a0823190602401602060405180830381865afa158015610f90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb49190611564565b9392505050565b60606106b484846000856060610fd0856110c9565b611006576040517f304619b500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161102f91906115e9565b60006040518083038185875af1925050503d806000811461106c576040519150601f19603f3d011682016040523d82523d6000602084013e611071565b606091505b509150915081156110855791506106b49050565b8051156110955780518082602001fd5b836040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ec99190611551565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906106b4575050151592915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561117857611178611102565b604052919050565b600082601f83011261119157600080fd5b813567ffffffffffffffff8111156111ab576111ab611102565b6111dc60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611131565b8181528460208386010111156111f157600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561122057600080fd5b813567ffffffffffffffff81111561123757600080fd5b6106b484828501611180565b600067ffffffffffffffff82111561125d5761125d611102565b5060051b60200190565b600082601f83011261127857600080fd5b8135602061128d61128883611243565b611131565b82815260059290921b840181019181810190868411156112ac57600080fd5b8286015b848110156112c757803583529183019183016112b0565b509695505050505050565b600080600080608085870312156112e857600080fd5b843567ffffffffffffffff8082111561130057600080fd5b61130c88838901611180565b955060209150818701358181111561132357600080fd5b61132f89828a01611267565b95505060408701358181111561134457600080fd5b8701601f8101891361135557600080fd5b803561136361128882611243565b81815260059190911b8201840190848101908b83111561138257600080fd5b928501925b828410156113b057833560ff811681146113a15760008081fd5b82529285019290850190611387565b965050505060608701359150808211156113c957600080fd5b506113d687828801611267565b91505092959194509250565b73ffffffffffffffffffffffffffffffffffffffff8116811461140457600080fd5b50565b60008060006060848603121561141c57600080fd5b8335611427816113e2565b92506020840135611437816113e2565b929592945050506040919091013590565b60005b8381101561146357818101518382015260200161144b565b838111156108185750506000910152565b6000815180845261148c816020860160208601611448565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60408152600c60408201527f4c697175697479436c61696d00000000000000000000000000000000000000006060820152608060208201526000610fb46080830184611474565b60006020828403121561151757600080fd5b8151610fb4816113e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602081526000610fb46020830184611474565b60006020828403121561157657600080fd5b5051919050565b600060ff821660ff8416808210156115be577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b90039392505050565b6000602082840312156115d957600080fd5b81518015158114610fb457600080fd5b600082516115fb818460208701611448565b919091019291505056fea2646970667358221220a6ed3c5b192eb74ca2df341dd847ac461df995269d35797cb9377d556391215d64736f6c634300080a0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.