Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
GUniWithdraw
Compiler Version
v0.7.6+commit.7338295f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-11-15 */ // SPDX-License-Identifier: MIT pragma solidity =0.7.6; pragma experimental ABIEncoderV2; abstract contract IDFSRegistry { function getAddr(bytes32 _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; } 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); } library Address { 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 { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } 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) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue( address target, bytes memory data, uint256 weiValue, string memory errorMessage ) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // 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"); } } } 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; 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 { require(admin == msg.sender, "msg.sender not admin"); owner = _owner; } /// @notice Admin is able to set new admin /// @param _admin Address of multisig that becomes new admin function changeAdmin(address _admin) public { require(admin == msg.sender, "msg.sender not admin"); admin = _admin; } } contract AdminAuth is AuthHelper { using SafeERC20 for IERC20; AdminVault public constant adminVault = AdminVault(ADMIN_VAULT_ADDR); modifier onlyOwner() { require(adminVault.owner() == msg.sender, "msg.sender not owner"); _; } modifier onlyAdmin() { require(adminVault.admin() == msg.sender, "msg.sender not admin"); _; } /// @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 DefisaverLogger { event LogEvent( address indexed contractAddress, address indexed caller, string indexed logName, bytes data ); // solhint-disable-next-line func-name-mixedcase function Log( address _contract, address _caller, string memory _logName, bytes memory _data ) public { emit LogEvent(_contract, _caller, _logName, _data); } } contract MainnetCoreAddresses { address internal constant DEFI_SAVER_LOGGER_ADDR = 0x5c55B921f590a89C1Ebe84dF170E655a82b62126; address internal constant REGISTRY_ADDR = 0xD6049E1F5F3EfF1F921f5532aF1A1632bA23929C; address internal constant PROXY_AUTH_ADDR = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF; } contract CoreHelper is MainnetCoreAddresses { } contract DFSRegistry is AdminAuth, CoreHelper { DefisaverLogger public constant logger = DefisaverLogger( DEFI_SAVER_LOGGER_ADDR ); string public constant ERR_ENTRY_ALREADY_EXISTS = "Entry id already exists"; string public constant ERR_ENTRY_NON_EXISTENT = "Entry id doesn't exists"; string public constant ERR_ENTRY_NOT_IN_CHANGE = "Entry not in change process"; string public constant ERR_WAIT_PERIOD_SHORTER = "New wait period must be bigger"; string public constant ERR_CHANGE_NOT_READY = "Change not ready yet"; string public constant ERR_EMPTY_PREV_ADDR = "Previous addr is 0"; string public constant ERR_ALREADY_IN_CONTRACT_CHANGE = "Already in contract change"; string public constant ERR_ALREADY_IN_WAIT_PERIOD_CHANGE = "Already in wait period change"; struct Entry { address contractAddr; uint256 waitPeriod; uint256 changeStartTime; bool inContractChange; bool inWaitPeriodChange; bool exists; } mapping(bytes32 => Entry) public entries; mapping(bytes32 => address) public previousAddresses; mapping(bytes32 => address) public pendingAddresses; mapping(bytes32 => 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(bytes32 _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(bytes32 _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( bytes32 _id, address _contractAddr, uint256 _waitPeriod ) public onlyOwner { require(!entries[_id].exists, ERR_ENTRY_ALREADY_EXISTS); entries[_id] = Entry({ contractAddr: _contractAddr, waitPeriod: _waitPeriod, changeStartTime: 0, inContractChange: false, inWaitPeriodChange: false, exists: true }); // Remember tha address so we can revert back to old addr if needed previousAddresses[_id] = _contractAddr; logger.Log( address(this), msg.sender, "AddNewContract", abi.encode(_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(bytes32 _id) public onlyOwner { require(entries[_id].exists, ERR_ENTRY_NON_EXISTENT); require(previousAddresses[_id] != address(0), ERR_EMPTY_PREV_ADDR); address currentAddr = entries[_id].contractAddr; entries[_id].contractAddr = previousAddresses[_id]; logger.Log( address(this), msg.sender, "RevertToPreviousAddress", abi.encode(_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(bytes32 _id, address _newContractAddr) public onlyOwner { require(entries[_id].exists, ERR_ENTRY_NON_EXISTENT); require(!entries[_id].inWaitPeriodChange, ERR_ALREADY_IN_WAIT_PERIOD_CHANGE); entries[_id].changeStartTime = block.timestamp; // solhint-disable-line entries[_id].inContractChange = true; pendingAddresses[_id] = _newContractAddr; logger.Log( address(this), msg.sender, "StartContractChange", abi.encode(_id, entries[_id].contractAddr, _newContractAddr) ); } /// @notice Changes new contract address, correct time must have passed /// @param _id Id of contract function approveContractChange(bytes32 _id) public onlyOwner { require(entries[_id].exists, ERR_ENTRY_NON_EXISTENT); require(entries[_id].inContractChange, ERR_ENTRY_NOT_IN_CHANGE); require( block.timestamp >= (entries[_id].changeStartTime + entries[_id].waitPeriod), // solhint-disable-line ERR_CHANGE_NOT_READY ); 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; logger.Log( address(this), msg.sender, "ApproveContractChange", abi.encode(_id, oldContractAddr, entries[_id].contractAddr) ); } /// @notice Cancel pending change /// @param _id Id of contract function cancelContractChange(bytes32 _id) public onlyOwner { require(entries[_id].exists, ERR_ENTRY_NON_EXISTENT); require(entries[_id].inContractChange, ERR_ENTRY_NOT_IN_CHANGE); address oldContractAddr = pendingAddresses[_id]; pendingAddresses[_id] = address(0); entries[_id].inContractChange = false; entries[_id].changeStartTime = 0; logger.Log( address(this), msg.sender, "CancelContractChange", abi.encode(_id, oldContractAddr, entries[_id].contractAddr) ); } /// @notice Starts the change for waitPeriod /// @param _id Id of contract /// @param _newWaitPeriod New wait time function startWaitPeriodChange(bytes32 _id, uint256 _newWaitPeriod) public onlyOwner { require(entries[_id].exists, ERR_ENTRY_NON_EXISTENT); require(!entries[_id].inContractChange, ERR_ALREADY_IN_CONTRACT_CHANGE); pendingWaitTimes[_id] = _newWaitPeriod; entries[_id].changeStartTime = block.timestamp; // solhint-disable-line entries[_id].inWaitPeriodChange = true; logger.Log( address(this), msg.sender, "StartWaitPeriodChange", abi.encode(_id, _newWaitPeriod) ); } /// @notice Changes new wait period, correct time must have passed /// @param _id Id of contract function approveWaitPeriodChange(bytes32 _id) public onlyOwner { require(entries[_id].exists, ERR_ENTRY_NON_EXISTENT); require(entries[_id].inWaitPeriodChange, ERR_ENTRY_NOT_IN_CHANGE); require( block.timestamp >= (entries[_id].changeStartTime + entries[_id].waitPeriod), // solhint-disable-line ERR_CHANGE_NOT_READY ); uint256 oldWaitTime = entries[_id].waitPeriod; entries[_id].waitPeriod = pendingWaitTimes[_id]; entries[_id].inWaitPeriodChange = false; entries[_id].changeStartTime = 0; pendingWaitTimes[_id] = 0; logger.Log( address(this), msg.sender, "ApproveWaitPeriodChange", abi.encode(_id, oldWaitTime, entries[_id].waitPeriod) ); } /// @notice Cancel wait period change /// @param _id Id of contract function cancelWaitPeriodChange(bytes32 _id) public onlyOwner { require(entries[_id].exists, ERR_ENTRY_NON_EXISTENT); require(entries[_id].inWaitPeriodChange, ERR_ENTRY_NOT_IN_CHANGE); uint256 oldWaitPeriod = pendingWaitTimes[_id]; pendingWaitTimes[_id] = 0; entries[_id].inWaitPeriodChange = false; entries[_id].changeStartTime = 0; logger.Log( address(this), msg.sender, "CancelWaitPeriodChange", abi.encode(_id, oldWaitPeriod, entries[_id].waitPeriod) ); } } contract MainnetActionsUtilAddresses { address internal constant DFS_REG_CONTROLLER_ADDR = 0xF8f8B3C98Cf2E63Df3041b73f80F362a4cf3A576; address internal constant REGISTRY_ADDR = 0xD6049E1F5F3EfF1F921f5532aF1A1632bA23929C; address internal constant DFS_LOGGER_ADDR = 0x5c55B921f590a89C1Ebe84dF170E655a82b62126; } contract ActionsUtilHelper is MainnetActionsUtilAddresses { } abstract contract ActionBase is AdminAuth, ActionsUtilHelper { DFSRegistry public constant registry = DFSRegistry(REGISTRY_ADDR); DefisaverLogger public constant logger = DefisaverLogger( DFS_LOGGER_ADDR ); string public constant ERR_SUB_INDEX_VALUE = "Wrong sub index value"; string public constant ERR_RETURN_INDEX_VALUE = "Wrong return index value"; /// @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, CUSTOM_ACTION } /// @notice Parses inputs and runs the implemented action through a proxy /// @dev Is called by the TaskExecutor 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, bytes[] 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, bytes[] memory _subData, bytes32[] memory _returnValues ) internal pure returns (uint) { if (isReplaceable(_mapType)) { if (isReturnInjection(_mapType)) { _param = uint(_returnValues[getReturnIndex(_mapType)]); } else { _param = abi.decode(_subData[getSubIndex(_mapType)], (uint)); } } 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, bytes[] memory _subData, bytes32[] memory _returnValues ) internal pure returns (address) { if (isReplaceable(_mapType)) { if (isReturnInjection(_mapType)) { _param = address(bytes20((_returnValues[getReturnIndex(_mapType)]))); } else { _param = abi.decode(_subData[getSubIndex(_mapType)], (address)); } } 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, bytes[] memory _subData, bytes32[] memory _returnValues ) internal pure returns (bytes32) { if (isReplaceable(_mapType)) { if (isReturnInjection(_mapType)) { _param = (_returnValues[getReturnIndex(_mapType)]); } else { _param = abi.decode(_subData[getSubIndex(_mapType)], (bytes32)); } } 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) { require(isReturnInjection(_type), ERR_SUB_INDEX_VALUE); 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) { require(_type >= SUB_MIN_INDEX_VALUE, ERR_RETURN_INDEX_VALUE); return (_type - SUB_MIN_INDEX_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 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(); } } contract DSMath { function add(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x + y) >= x, ""); } function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x - y) <= x, ""); } function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { require(y == 0 || (z = x * y) / y == x, ""); } function div(uint256 x, uint256 y) internal pure returns (uint256 z) { return x / y; } function min(uint256 x, uint256 y) internal pure returns (uint256 z) { return x <= y ? x : y; } function max(uint256 x, uint256 y) internal pure returns (uint256 z) { return x >= y ? x : y; } function imin(int256 x, int256 y) internal pure returns (int256 z) { return x <= y ? x : y; } function imax(int256 x, int256 y) internal pure returns (int256 z) { return x >= y ? x : y; } uint256 constant WAD = 10**18; uint256 constant RAY = 10**27; function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, y), WAD / 2) / WAD; } function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, y), RAY / 2) / RAY; } function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, WAD), y / 2) / y; } function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { z = add(mul(x, RAY), y / 2) / y; } // This famous algorithm is called "exponentiation by squaring" // and calculates x^n with x as fixed-point and n as regular unsigned. // // It's O(log n), instead of O(n) for naive repeated multiplication. // // These facts are why it works: // // If n is even, then x^n = (x^2)^(n/2). // If n is odd, then x^n = x * x^(n-1), // and applying the equation for even x gives // x^n = x * (x^2)^((n-1) / 2). // // Also, EVM division is flooring and // floor[(n-1) / 2] = floor[n / 2]. // function rpow(uint256 x, uint256 n) internal pure returns (uint256 z) { z = n % 2 != 0 ? x : RAY; for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } } contract MainnetGUniAddresses { address public constant G_UNI_ROUTER_02_ADDRESS = 0x14E6D67F824C3a7b4329d3228807f8654294e4bd; } interface IGUniRouter02 { function removeLiquidity( address pool, uint256 burnAmount, uint256 amount0Min, uint256 amount1Min, address receiver ) external returns ( uint256 amount0, uint256 amount1, uint128 liquidityBurned ); function rebalanceAndAddLiquidity( address pool, uint256 amount0In, uint256 amount1In, uint256 amountSwap, bool zeroForOne, address[] memory swapActions, bytes[] memory swapDatas, uint256 amount0Min, uint256 amount1Min, address receiver ) external returns ( uint256 amount0, uint256 amount1, uint256 mintAmount ); function addLiquidity( address pool, uint256 amount0Max, uint256 amount1Max, uint256 amount0Min, uint256 amount1Min, address receiver ) external returns ( uint256 amount0, uint256 amount1, uint256 mintAmount ); } contract GUniHelper is MainnetGUniAddresses{ IGUniRouter02 public constant gUniRouter = IGUniRouter02(G_UNI_ROUTER_02_ADDRESS); } contract GUniWithdraw is ActionBase, DSMath, GUniHelper { using TokenUtils for address; /// @param pool address of G-UNI pool to remove liquidity from /// @param burnAmount The number of G-UNI tokens to burn /// @param amount0Min Minimum amount of token0 received after burn (slippage protection) /// @param amount1Min Minimum amount of token1 received after burn (slippage protection) /// @param to The account to receive the underlying amounts of token0 and token1 /// @param from Account from which to pull G-Uni LP tokens struct Params { address pool; uint256 burnAmount; uint256 amount0Min; uint256 amount1Min; address to; address from; } /// @inheritdoc ActionBase function executeAction( bytes[] memory _callData, bytes[] memory _subData, uint8[] memory _paramMapping, bytes32[] memory _returnValues ) public payable virtual override returns (bytes32) { Params memory inputData = parseInputs(_callData); inputData.burnAmount = _parseParamUint(inputData.burnAmount, _paramMapping[0], _subData, _returnValues); uint256 liquidityBurnt = gUniWithdraw(inputData); return bytes32(liquidityBurnt); } /// @inheritdoc ActionBase function executeActionDirect(bytes[] memory _callData) public payable override { Params memory inputData = parseInputs(_callData); gUniWithdraw(inputData); } /// @inheritdoc ActionBase function actionType() public pure virtual override returns (uint8) { return uint8(ActionType.STANDARD_ACTION); } //////////////////////////// ACTION LOGIC //////////////////////////// function gUniWithdraw(Params memory _inputData) internal returns (uint128) { require (_inputData.to != address(0x0), "Can not send to burn address"); _inputData.burnAmount = _inputData.pool.pullTokensIfNeeded(_inputData.from, _inputData.burnAmount); _inputData.pool.approveToken(G_UNI_ROUTER_02_ADDRESS, _inputData.burnAmount); (uint256 amount0, uint256 amount1, uint128 liquidityBurnt) = gUniRouter.removeLiquidity(_inputData.pool, _inputData.burnAmount, _inputData.amount0Min, _inputData.amount1Min, _inputData.to); /// @dev amountToBurn will always be burnt, so no need to send back any leftovers logger.Log(address(this), msg.sender, "GUniWithdraw", abi.encode(_inputData, amount0, amount1, liquidityBurnt)); return liquidityBurnt; } function parseInputs(bytes[] memory _callData) internal pure returns (Params memory inputData) { inputData = abi.decode(_callData[0], (Params)); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"ERR_RETURN_INDEX_VALUE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERR_SUB_INDEX_VALUE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"G_UNI_ROUTER_02_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NO_PARAM_MAPPING","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"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":"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":"bytes[]","name":"_subData","type":"bytes[]"},{"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":"gUniRouter","outputs":[{"internalType":"contract IGUniRouter02","name":"","type":"address"}],"stateMutability":"view","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
608060405234801561001057600080fd5b5061166e806100206000396000f3fe60806040526004361061010e5760003560e01c8063910c238e116100a5578063ca5ff78011610074578063e910afb211610059578063e910afb21461025d578063f24ccbfe1461027f578063f8e2fb00146102945761010e565b8063ca5ff78014610228578063d3c2e7ed146102485761010e565b8063910c238e146101de5780639864dcdd146101f3578063b45151e1146101de578063c579d490146102085761010e565b806341c0e1b5116100e157806341c0e1b51461017d5780637b103999146101925780638bcb6216146101b45780638cedca71146101c95761010e565b80630f2eee42146101135780631afd15be1461013e578063247492f8146101535780632fa13cb814610168575b600080fd5b34801561011f57600080fd5b506101286102a9565b60405161013591906115a4565b60405180910390f35b61015161014c366004611028565b6102ae565b005b34801561015f57600080fd5b506101286102c9565b34801561017457600080fd5b506101286102ce565b34801561018957600080fd5b506101516102d3565b34801561019e57600080fd5b506101a7610394565b60405161013591906112bc565b3480156101c057600080fd5b506101286103ac565b3480156101d557600080fd5b506101a76103b1565b3480156101ea57600080fd5b506101a76103c9565b3480156101ff57600080fd5b506101286103e1565b34801561021457600080fd5b50610151610223366004610fe8565b6103e6565b61023b61023636600461105b565b610510565b60405161013591906113dc565b34801561025457600080fd5b50610128610571565b34801561026957600080fd5b50610272610576565b60405161013591906113e5565b34801561028b57600080fd5b506101a76105af565b3480156102a057600080fd5b506102726105c7565b608081565b60006102b982610600565b90506102c481610636565b505050565b600190565b600081565b336001600160a01b031673ccf3d848e08b94478ed8f46ffead3008faf581fd6001600160a01b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561032a57600080fd5b505afa15801561033e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103629190610fcc565b6001600160a01b0316146103915760405162461bcd60e51b815260040161038890611466565b60405180910390fd5b33ff5b73d6049e1f5f3eff1f921f5532af1a1632ba23929c81565b600181565b73ccf3d848e08b94478ed8f46ffead3008faf581fd81565b7314e6d67f824c3a7b4329d3228807f8654294e4bd81565b607f81565b336001600160a01b031673ccf3d848e08b94478ed8f46ffead3008faf581fd6001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561043d57600080fd5b505afa158015610451573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104759190610fcc565b6001600160a01b03161461049b5760405162461bcd60e51b81526004016103889061142f565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b03841614156104fc576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156104f6573d6000803e3d6000fd5b506102c4565b6102c46001600160a01b0384168383610823565b60008061051c86610600565b905061054281602001518560008151811061053357fe5b602002602001015187866108a6565b6020820152600061055282610636565b6fffffffffffffffffffffffffffffffff16925050505b949350505050565b60ff81565b6040518060400160405280601881526020017f57726f6e672072657475726e20696e6465782076616c7565000000000000000081525081565b735c55b921f590a89c1ebe84df170e655a82b6212681565b6040518060400160405280601581526020017f57726f6e672073756220696e6465782076616c7565000000000000000000000081525081565b610608610e5a565b8160008151811061061557fe5b60200260200101518060200190518101906106309190611185565b92915050565b60808101516000906001600160a01b03166106635760405162461bcd60e51b8152600401610388906113f8565b60a082015160208301518351610684926001600160a01b039091169161092b565b6020830181905282516106b8916001600160a01b03909116907314e6d67f824c3a7b4329d3228807f8654294e4bd906109ba565b815160208301516040808501516060860151608087015192517f59f842b2000000000000000000000000000000000000000000000000000000008152600095869586957314e6d67f824c3a7b4329d3228807f8654294e4bd956359f842b29561072795919290916004016113ac565b606060405180830381600087803b15801561074157600080fd5b505af1158015610755573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107799190611228565b925092509250735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce503033888787876040516020016107bb9493929190611531565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016107e8939291906112ea565b600060405180830381600087803b15801561080257600080fd5b505af1158015610816573d6000803e3d6000fd5b5092979650505050505050565b6102c48363a9059cbb60e01b8484604051602401610842929190611393565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610a97565b60006108b184610b26565b15610922576108bf84610b2e565b156108ed57816108ce85610b4d565b60ff16815181106108db57fe5b602002602001015160001c9450610922565b826108f785610bb5565b60ff168151811061090457fe5b602002602001015180602001905181019061091f9190611210565b94505b50929392505050565b6000600019821415610944576109418484610c1a565b91505b6001600160a01b0383161580159061096557506001600160a01b0383163014155b801561098e57506001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b801561099957508115155b156109b3576109b36001600160a01b038516843085610cee565b5092915050565b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156109e4576102c4565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815281906001600160a01b0385169063dd62ed3e90610a2d90309087906004016112d0565b60206040518083038186803b158015610a4557600080fd5b505afa158015610a59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7d9190611210565b10156102c4576102c46001600160a01b0384168383610d15565b6000610aec826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610d549092919063ffffffff16565b8051909150156102c45780806020019051810190610b0a9190611165565b6102c45760405162461bcd60e51b8152600401610388906114d4565b60ff16151590565b6000600160ff831610801590610630575050607f60ff91909116111590565b6000610b5882610b2e565b6040518060400160405280601581526020017f57726f6e672073756220696e6465782076616c7565000000000000000000000081525090610bac5760405162461bcd60e51b815260040161038891906113e5565b50506000190190565b60408051808201909152601881527f57726f6e672072657475726e20696e6465782076616c756500000000000000006020820152600090608060ff84161015610c115760405162461bcd60e51b815260040161038891906113e5565b5050607f190190565b60006001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610c5257506001600160a01b03811631610630565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038416906370a0823190610c979085906004016112bc565b60206040518083038186803b158015610caf57600080fd5b505afa158015610cc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce79190611210565b9392505050565b610d0f846323b872dd60e01b85858560405160240161084293929190611353565b50505050565b610d358363095ea7b360e01b846000604051602401610842929190611377565b6102c48363095ea7b360e01b8484604051602401610842929190611393565b606061056984846000856060610d6985610e21565b610d855760405162461bcd60e51b81526004016103889061149d565b600080866001600160a01b03168587604051610da191906112a0565b60006040518083038185875af1925050503d8060008114610dde576040519150601f19603f3d011682016040523d82523d6000602084013e610de3565b606091505b50915091508115610df75791506105699050565b805115610e075780518082602001fd5b8360405162461bcd60e51b815260040161038891906113e5565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610569575050151592915050565b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681525090565b600082601f830112610ebb578081fd5b81356020610ed0610ecb836115d6565b6115b2565b8281528181019085830183850287018401881015610eec578586fd5b855b85811015610f0a57813584529284019290840190600101610eee565b5090979650505050505050565b6000601f8381840112610f28578182fd5b82356020610f38610ecb836115d6565b82815281810190868301865b85811015610fbe57813589018a603f820112610f5e578889fd5b85810135604067ffffffffffffffff821115610f7657fe5b610f87828b01601f191689016115b2565b8281528d82848601011115610f9a578b8cfd5b828285018a83013791820188018b9052508552509284019290840190600101610f44565b509098975050505050505050565b600060208284031215610fdd578081fd5b8151610ce781611620565b600080600060608486031215610ffc578182fd5b833561100781611620565b9250602084013561101781611620565b929592945050506040919091013590565b600060208284031215611039578081fd5b813567ffffffffffffffff81111561104f578182fd5b61056984828501610f17565b60008060008060808587031215611070578081fd5b843567ffffffffffffffff80821115611087578283fd5b61109388838901610f17565b95506020915081870135818111156110a9578384fd5b6110b589828a01610f17565b9550506040870135818111156110c9578384fd5b8701601f810189136110d9578384fd5b80356110e7610ecb826115d6565b81815284810190838601868402850187018d1015611103578788fd5b8794505b8385101561113357803560ff8116811461111f578889fd5b835260019490940193918601918601611107565b509650505050606087013591508082111561114c578283fd5b5061115987828801610eab565b91505092959194509250565b600060208284031215611176578081fd5b81518015158114610ce7578182fd5b600060c08284031215611196578081fd5b60405160c0810181811067ffffffffffffffff821117156111b357fe5b60405282516111c181611620565b8082525060208301516020820152604083015160408201526060830151606082015260808301516111f181611620565b608082015260a083015161120481611620565b60a08201529392505050565b600060208284031215611221578081fd5b5051919050565b60008060006060848603121561123c578081fd5b835192506020840151915060408401516fffffffffffffffffffffffffffffffff81168114611269578182fd5b809150509250925092565b6000815180845261128c8160208601602086016115f4565b601f01601f19169290920160200192915050565b600082516112b28184602087016115f4565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006001600160a01b03808616835280851660208401525060806040830152600c60808301527f47556e695769746864726177000000000000000000000000000000000000000060a083015260c0606083015261134a60c0830184611274565b95945050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0392909216825260ff16602082015260400190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039586168152602081019490945260408401929092526060830152909116608082015260a00190565b90815260200190565b600060208252610ce76020830184611274565b6020808252601c908201527f43616e206e6f742073656e6420746f206275726e206164647265737300000000604082015260600190565b60208082526014908201527f6d73672e73656e646572206e6f74206f776e6572000000000000000000000000604082015260600190565b60208082526014908201527f6d73672e73656e646572206e6f742061646d696e000000000000000000000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60408201527f6f74207375636365656400000000000000000000000000000000000000000000606082015260800190565b84516001600160a01b03908116825260208087015190830152604080870151908301526060808701519083015260808087015182169083015260a095860151169481019490945260c084019290925260e08301526fffffffffffffffffffffffffffffffff166101008201526101200190565b60ff91909116815260200190565b60405181810167ffffffffffffffff811182821017156115ce57fe5b604052919050565b600067ffffffffffffffff8211156115ea57fe5b5060209081020190565b60005b8381101561160f5781810151838201526020016115f7565b83811115610d0f5750506000910152565b6001600160a01b038116811461163557600080fd5b5056fea26469706673582212200d948554a76571517b6930167951bf039c8f87feae6d9ff1eeb90c7653d9619c64736f6c63430007060033
Deployed Bytecode
0x60806040526004361061010e5760003560e01c8063910c238e116100a5578063ca5ff78011610074578063e910afb211610059578063e910afb21461025d578063f24ccbfe1461027f578063f8e2fb00146102945761010e565b8063ca5ff78014610228578063d3c2e7ed146102485761010e565b8063910c238e146101de5780639864dcdd146101f3578063b45151e1146101de578063c579d490146102085761010e565b806341c0e1b5116100e157806341c0e1b51461017d5780637b103999146101925780638bcb6216146101b45780638cedca71146101c95761010e565b80630f2eee42146101135780631afd15be1461013e578063247492f8146101535780632fa13cb814610168575b600080fd5b34801561011f57600080fd5b506101286102a9565b60405161013591906115a4565b60405180910390f35b61015161014c366004611028565b6102ae565b005b34801561015f57600080fd5b506101286102c9565b34801561017457600080fd5b506101286102ce565b34801561018957600080fd5b506101516102d3565b34801561019e57600080fd5b506101a7610394565b60405161013591906112bc565b3480156101c057600080fd5b506101286103ac565b3480156101d557600080fd5b506101a76103b1565b3480156101ea57600080fd5b506101a76103c9565b3480156101ff57600080fd5b506101286103e1565b34801561021457600080fd5b50610151610223366004610fe8565b6103e6565b61023b61023636600461105b565b610510565b60405161013591906113dc565b34801561025457600080fd5b50610128610571565b34801561026957600080fd5b50610272610576565b60405161013591906113e5565b34801561028b57600080fd5b506101a76105af565b3480156102a057600080fd5b506102726105c7565b608081565b60006102b982610600565b90506102c481610636565b505050565b600190565b600081565b336001600160a01b031673ccf3d848e08b94478ed8f46ffead3008faf581fd6001600160a01b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561032a57600080fd5b505afa15801561033e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103629190610fcc565b6001600160a01b0316146103915760405162461bcd60e51b815260040161038890611466565b60405180910390fd5b33ff5b73d6049e1f5f3eff1f921f5532af1a1632ba23929c81565b600181565b73ccf3d848e08b94478ed8f46ffead3008faf581fd81565b7314e6d67f824c3a7b4329d3228807f8654294e4bd81565b607f81565b336001600160a01b031673ccf3d848e08b94478ed8f46ffead3008faf581fd6001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561043d57600080fd5b505afa158015610451573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104759190610fcc565b6001600160a01b03161461049b5760405162461bcd60e51b81526004016103889061142f565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b03841614156104fc576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156104f6573d6000803e3d6000fd5b506102c4565b6102c46001600160a01b0384168383610823565b60008061051c86610600565b905061054281602001518560008151811061053357fe5b602002602001015187866108a6565b6020820152600061055282610636565b6fffffffffffffffffffffffffffffffff16925050505b949350505050565b60ff81565b6040518060400160405280601881526020017f57726f6e672072657475726e20696e6465782076616c7565000000000000000081525081565b735c55b921f590a89c1ebe84df170e655a82b6212681565b6040518060400160405280601581526020017f57726f6e672073756220696e6465782076616c7565000000000000000000000081525081565b610608610e5a565b8160008151811061061557fe5b60200260200101518060200190518101906106309190611185565b92915050565b60808101516000906001600160a01b03166106635760405162461bcd60e51b8152600401610388906113f8565b60a082015160208301518351610684926001600160a01b039091169161092b565b6020830181905282516106b8916001600160a01b03909116907314e6d67f824c3a7b4329d3228807f8654294e4bd906109ba565b815160208301516040808501516060860151608087015192517f59f842b2000000000000000000000000000000000000000000000000000000008152600095869586957314e6d67f824c3a7b4329d3228807f8654294e4bd956359f842b29561072795919290916004016113ac565b606060405180830381600087803b15801561074157600080fd5b505af1158015610755573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107799190611228565b925092509250735c55b921f590a89c1ebe84df170e655a82b621266001600160a01b031663d061ce503033888787876040516020016107bb9493929190611531565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016107e8939291906112ea565b600060405180830381600087803b15801561080257600080fd5b505af1158015610816573d6000803e3d6000fd5b5092979650505050505050565b6102c48363a9059cbb60e01b8484604051602401610842929190611393565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152610a97565b60006108b184610b26565b15610922576108bf84610b2e565b156108ed57816108ce85610b4d565b60ff16815181106108db57fe5b602002602001015160001c9450610922565b826108f785610bb5565b60ff168151811061090457fe5b602002602001015180602001905181019061091f9190611210565b94505b50929392505050565b6000600019821415610944576109418484610c1a565b91505b6001600160a01b0383161580159061096557506001600160a01b0383163014155b801561098e57506001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b801561099957508115155b156109b3576109b36001600160a01b038516843085610cee565b5092915050565b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156109e4576102c4565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815281906001600160a01b0385169063dd62ed3e90610a2d90309087906004016112d0565b60206040518083038186803b158015610a4557600080fd5b505afa158015610a59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7d9190611210565b10156102c4576102c46001600160a01b0384168383610d15565b6000610aec826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610d549092919063ffffffff16565b8051909150156102c45780806020019051810190610b0a9190611165565b6102c45760405162461bcd60e51b8152600401610388906114d4565b60ff16151590565b6000600160ff831610801590610630575050607f60ff91909116111590565b6000610b5882610b2e565b6040518060400160405280601581526020017f57726f6e672073756220696e6465782076616c7565000000000000000000000081525090610bac5760405162461bcd60e51b815260040161038891906113e5565b50506000190190565b60408051808201909152601881527f57726f6e672072657475726e20696e6465782076616c756500000000000000006020820152600090608060ff84161015610c115760405162461bcd60e51b815260040161038891906113e5565b5050607f190190565b60006001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610c5257506001600160a01b03811631610630565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038416906370a0823190610c979085906004016112bc565b60206040518083038186803b158015610caf57600080fd5b505afa158015610cc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce79190611210565b9392505050565b610d0f846323b872dd60e01b85858560405160240161084293929190611353565b50505050565b610d358363095ea7b360e01b846000604051602401610842929190611377565b6102c48363095ea7b360e01b8484604051602401610842929190611393565b606061056984846000856060610d6985610e21565b610d855760405162461bcd60e51b81526004016103889061149d565b600080866001600160a01b03168587604051610da191906112a0565b60006040518083038185875af1925050503d8060008114610dde576040519150601f19603f3d011682016040523d82523d6000602084013e610de3565b606091505b50915091508115610df75791506105699050565b805115610e075780518082602001fd5b8360405162461bcd60e51b815260040161038891906113e5565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610569575050151592915050565b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681525090565b600082601f830112610ebb578081fd5b81356020610ed0610ecb836115d6565b6115b2565b8281528181019085830183850287018401881015610eec578586fd5b855b85811015610f0a57813584529284019290840190600101610eee565b5090979650505050505050565b6000601f8381840112610f28578182fd5b82356020610f38610ecb836115d6565b82815281810190868301865b85811015610fbe57813589018a603f820112610f5e578889fd5b85810135604067ffffffffffffffff821115610f7657fe5b610f87828b01601f191689016115b2565b8281528d82848601011115610f9a578b8cfd5b828285018a83013791820188018b9052508552509284019290840190600101610f44565b509098975050505050505050565b600060208284031215610fdd578081fd5b8151610ce781611620565b600080600060608486031215610ffc578182fd5b833561100781611620565b9250602084013561101781611620565b929592945050506040919091013590565b600060208284031215611039578081fd5b813567ffffffffffffffff81111561104f578182fd5b61056984828501610f17565b60008060008060808587031215611070578081fd5b843567ffffffffffffffff80821115611087578283fd5b61109388838901610f17565b95506020915081870135818111156110a9578384fd5b6110b589828a01610f17565b9550506040870135818111156110c9578384fd5b8701601f810189136110d9578384fd5b80356110e7610ecb826115d6565b81815284810190838601868402850187018d1015611103578788fd5b8794505b8385101561113357803560ff8116811461111f578889fd5b835260019490940193918601918601611107565b509650505050606087013591508082111561114c578283fd5b5061115987828801610eab565b91505092959194509250565b600060208284031215611176578081fd5b81518015158114610ce7578182fd5b600060c08284031215611196578081fd5b60405160c0810181811067ffffffffffffffff821117156111b357fe5b60405282516111c181611620565b8082525060208301516020820152604083015160408201526060830151606082015260808301516111f181611620565b608082015260a083015161120481611620565b60a08201529392505050565b600060208284031215611221578081fd5b5051919050565b60008060006060848603121561123c578081fd5b835192506020840151915060408401516fffffffffffffffffffffffffffffffff81168114611269578182fd5b809150509250925092565b6000815180845261128c8160208601602086016115f4565b601f01601f19169290920160200192915050565b600082516112b28184602087016115f4565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b60006001600160a01b03808616835280851660208401525060806040830152600c60808301527f47556e695769746864726177000000000000000000000000000000000000000060a083015260c0606083015261134a60c0830184611274565b95945050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0392909216825260ff16602082015260400190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039586168152602081019490945260408401929092526060830152909116608082015260a00190565b90815260200190565b600060208252610ce76020830184611274565b6020808252601c908201527f43616e206e6f742073656e6420746f206275726e206164647265737300000000604082015260600190565b60208082526014908201527f6d73672e73656e646572206e6f74206f776e6572000000000000000000000000604082015260600190565b60208082526014908201527f6d73672e73656e646572206e6f742061646d696e000000000000000000000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60408201527f6f74207375636365656400000000000000000000000000000000000000000000606082015260800190565b84516001600160a01b03908116825260208087015190830152604080870151908301526060808701519083015260808087015182169083015260a095860151169481019490945260c084019290925260e08301526fffffffffffffffffffffffffffffffff166101008201526101200190565b60ff91909116815260200190565b60405181810167ffffffffffffffff811182821017156115ce57fe5b604052919050565b600067ffffffffffffffff8211156115ea57fe5b5060209081020190565b60005b8381101561160f5781810151838201526020016115f7565b83811115610d0f5750506000910152565b6001600160a01b038116811461163557600080fd5b5056fea26469706673582212200d948554a76571517b6930167951bf039c8f87feae6d9ff1eeb90c7653d9619c64736f6c63430007060033
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.