Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
18883980 | 361 days ago | 0.16856772 ETH | ||||
18883980 | 361 days ago | 0.16856772 ETH | ||||
17854599 | 505 days ago | 0.01 ETH | ||||
17854599 | 505 days ago | 0.01 ETH | ||||
17853779 | 506 days ago | 0.03241245 ETH | ||||
17853779 | 506 days ago | 0.03241245 ETH | ||||
17853649 | 506 days ago | 0.1 ETH | ||||
17853649 | 506 days ago | 0.1 ETH | ||||
17853569 | 506 days ago | 0.15 ETH | ||||
17853569 | 506 days ago | 0.15 ETH | ||||
17835153 | 508 days ago | 0.02 ETH | ||||
17835153 | 508 days ago | 0.02 ETH | ||||
17833793 | 508 days ago | 0.32567023 ETH | ||||
17833793 | 508 days ago | 0.32567023 ETH | ||||
17808804 | 512 days ago | 0.02 ETH | ||||
17808804 | 512 days ago | 0.02 ETH | ||||
17807530 | 512 days ago | 0.0054 ETH | ||||
17807530 | 512 days ago | 0.0054 ETH | ||||
17804702 | 512 days ago | 0.00992334 ETH | ||||
17804702 | 512 days ago | 0.00992334 ETH | ||||
17791434 | 514 days ago | 0.01664774 ETH | ||||
17791434 | 514 days ago | 0.01664774 ETH | ||||
17777435 | 516 days ago | 0.03 ETH | ||||
17777435 | 516 days ago | 0.03 ETH | ||||
17774709 | 517 days ago | 0.06600202 ETH |
Loading...
Loading
Contract Name:
TransformerRegistry
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
Yes with 9999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.7 <0.9.0; import '@openzeppelin/contracts/utils/introspection/ERC165Checker.sol'; import './transformers/BaseTransformer.sol'; import '../interfaces/ITransformerRegistry.sol'; contract TransformerRegistry is BaseTransformer, ITransformerRegistry { mapping(address => ITransformer) internal _registeredTransformer; // dependent => transformer constructor(address _governor) Governable(_governor) {} /// @inheritdoc ITransformerRegistry function transformers(address[] calldata _dependents) external view returns (ITransformer[] memory _transformers) { _transformers = new ITransformer[](_dependents.length); for (uint256 i; i < _dependents.length; i++) { _transformers[i] = _registeredTransformer[_dependents[i]]; } } /// @inheritdoc ITransformerRegistry function registerTransformers(TransformerRegistration[] calldata _registrations) external onlyGovernor { for (uint256 i; i < _registrations.length; i++) { TransformerRegistration memory _registration = _registrations[i]; // Make sure the given address is actually a transformer bool _isTransformer = ERC165Checker.supportsInterface(_registration.transformer, type(ITransformer).interfaceId); if (!_isTransformer) revert AddressIsNotTransformer(_registration.transformer); for (uint256 j; j < _registration.dependents.length; j++) { _registeredTransformer[_registration.dependents[j]] = ITransformer(_registration.transformer); } } emit TransformersRegistered(_registrations); } /// @inheritdoc ITransformerRegistry function removeTransformers(address[] calldata _dependents) external onlyGovernor { for (uint256 i; i < _dependents.length; i++) { _registeredTransformer[_dependents[i]] = ITransformer(address(0)); } emit TransformersRemoved(_dependents); } /// @inheritdoc ITransformer function getUnderlying(address _dependent) external view returns (address[] memory) { ITransformer _transformer = _getTransformerOrFail(_dependent); return _transformer.getUnderlying(_dependent); } /// @inheritdoc ITransformer function calculateTransformToUnderlying(address _dependent, uint256 _amountDependent) external view returns (UnderlyingAmount[] memory) { ITransformer _transformer = _getTransformerOrFail(_dependent); return _transformer.calculateTransformToUnderlying(_dependent, _amountDependent); } /// @inheritdoc ITransformer function calculateTransformToDependent(address _dependent, UnderlyingAmount[] calldata _underlying) external view returns (uint256 _amountDependent) { ITransformer _transformer = _getTransformerOrFail(_dependent); return _transformer.calculateTransformToDependent(_dependent, _underlying); } /// @inheritdoc ITransformer function calculateNeededToTransformToUnderlying(address _dependent, UnderlyingAmount[] calldata _expectedUnderlying) external view returns (uint256 _neededDependent) { ITransformer _transformer = _getTransformerOrFail(_dependent); return _transformer.calculateNeededToTransformToUnderlying(_dependent, _expectedUnderlying); } /// @inheritdoc ITransformer function calculateNeededToTransformToDependent(address _dependent, uint256 _expectedDependent) external view returns (UnderlyingAmount[] memory _neededUnderlying) { ITransformer _transformer = _getTransformerOrFail(_dependent); return _transformer.calculateNeededToTransformToDependent(_dependent, _expectedDependent); } /// @inheritdoc ITransformer function transformToUnderlying( address _dependent, uint256 _amountDependent, address _recipient, UnderlyingAmount[] calldata _minAmountOut, uint256 _deadline ) external payable returns (UnderlyingAmount[] memory) { ITransformer _transformer = _getTransformerOrFail(_dependent); bytes memory _result = _delegateToTransformer( _transformer, abi.encodeWithSelector(_transformer.transformToUnderlying.selector, _dependent, _amountDependent, _recipient, _minAmountOut, _deadline) ); return abi.decode(_result, (UnderlyingAmount[])); } /// @inheritdoc ITransformer function transformToDependent( address _dependent, UnderlyingAmount[] calldata _underlying, address _recipient, uint256 _minAmountOut, uint256 _deadline ) external payable returns (uint256 _amountDependent) { ITransformer _transformer = _getTransformerOrFail(_dependent); bytes memory _result = _delegateToTransformer( _transformer, abi.encodeWithSelector(_transformer.transformToDependent.selector, _dependent, _underlying, _recipient, _minAmountOut, _deadline) ); return abi.decode(_result, (uint256)); } /// @inheritdoc ITransformerRegistry function transformAllToUnderlying( address _dependent, address _recipient, UnderlyingAmount[] memory _minAmountOut, uint256 _deadline ) external payable returns (UnderlyingAmount[] memory) { ITransformer _transformer = _getTransformerOrFail(_dependent); uint256 _amountDependent = IERC20(_dependent).balanceOf(msg.sender); bytes memory _result = _delegateToTransformer( _transformer, abi.encodeWithSelector(_transformer.transformToUnderlying.selector, _dependent, _amountDependent, _recipient, _minAmountOut, _deadline) ); return abi.decode(_result, (UnderlyingAmount[])); } /// @inheritdoc ITransformerRegistry function transformAllToDependent( address _dependent, address _recipient, uint256 _minAmountOut, uint256 _deadline ) external payable returns (uint256) { ITransformer _transformer = _getTransformerOrFail(_dependent); // Calculate underlying address[] memory _underlying = _transformer.getUnderlying(_dependent); UnderlyingAmount[] memory _underlyingAmount = new UnderlyingAmount[](_underlying.length); for (uint256 i; i < _underlying.length; i++) { address _underlyingToken = _underlying[i]; uint256 _balance = _underlyingToken == PROTOCOL_TOKEN ? address(this).balance : IERC20(_underlyingToken).balanceOf(msg.sender); _underlyingAmount[i] = UnderlyingAmount({underlying: _underlyingToken, amount: _balance}); } // Delegate bytes memory _result = _delegateToTransformer( _transformer, abi.encodeWithSelector(_transformer.transformToDependent.selector, _dependent, _underlyingAmount, _recipient, _minAmountOut, _deadline) ); return abi.decode(_result, (uint256)); } /// @inheritdoc ITransformer function transformToExpectedUnderlying( address _dependent, UnderlyingAmount[] calldata _expectedUnderlying, address _recipient, uint256 _maxAmountIn, uint256 _deadline ) external payable returns (uint256 _spentDependent) { ITransformer _transformer = _getTransformerOrFail(_dependent); bytes memory _result = _delegateToTransformer( _transformer, abi.encodeWithSelector( _transformer.transformToExpectedUnderlying.selector, _dependent, _expectedUnderlying, _recipient, _maxAmountIn, _deadline ) ); return abi.decode(_result, (uint256)); } /// @inheritdoc ITransformer function transformToExpectedDependent( address _dependent, uint256 _expectedDependent, address _recipient, UnderlyingAmount[] calldata _maxAmountIn, uint256 _deadline ) external payable returns (UnderlyingAmount[] memory _spentUnderlying) { ITransformer _transformer = _getTransformerOrFail(_dependent); bytes memory _result = _delegateToTransformer( _transformer, abi.encodeWithSelector( _transformer.transformToExpectedDependent.selector, _dependent, _expectedDependent, _recipient, _maxAmountIn, _deadline ) ); return abi.decode(_result, (UnderlyingAmount[])); } receive() external payable {} function _getTransformerOrFail(address _dependent) internal view returns (ITransformer _transformer) { _transformer = _registeredTransformer[_dependent]; if (address(_transformer) == address(0)) revert NoTransformerRegistered(_dependent); } function _delegateToTransformer(ITransformer _transformer, bytes memory _data) internal returns (bytes memory) { return Address.functionDelegateCall(address(_transformer), _data); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.2) (utils/introspection/ERC165Checker.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface, */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return _supportsERC165Interface(account, type(IERC165).interfaceId) && !_supportsERC165Interface(account, _INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && _supportsERC165Interface(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. * * _Available since v3.4._ */ function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in _interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!_supportsERC165Interface(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * Interface identification is specified in ERC-165. */ function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) { // prepare call bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId); // perform static call bool success; uint256 returnSize; uint256 returnValue; assembly { success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) returnSize := returndatasize() returnValue := mload(0x00) } return success && returnSize >= 0x20 && returnValue > 0; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.7 <0.9.0; import '@openzeppelin/contracts/utils/introspection/ERC165.sol'; import '../../interfaces/ITransformer.sol'; import '../utils/CollectableDust.sol'; import '../utils/Multicall.sol'; /// @title A base implementation of `ITransformer` that implements `CollectableDust` and `Multicall` abstract contract BaseTransformer is CollectableDust, Multicall, ERC165, ITransformer { /// @inheritdoc IERC165 function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { return _interfaceId == type(ITransformer).interfaceId || _interfaceId == type(IGovernable).interfaceId || _interfaceId == type(ICollectableDust).interfaceId || _interfaceId == type(IMulticall).interfaceId || super.supportsInterface(_interfaceId); } modifier checkDeadline(uint256 _deadline) { if (block.timestamp > _deadline) revert TransactionExpired(); _; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; import './ITransformer.sol'; /** * @title A registry for all existing transformers * @notice This contract will contain all registered transformers and act as proxy. When called * the registry will find the corresponding transformer and delegate the call to it. If no * transformer is found, then it will fail */ interface ITransformerRegistry is ITransformer { /// @notice An association between a transformer, and some of its dependentes struct TransformerRegistration { address transformer; address[] dependents; } /** * @notice Thrown when trying to register a dependent to an address that is not a transformer * @param account The account that was not a transformer */ error AddressIsNotTransformer(address account); /** * @notice Thrown when trying to execute an action with a dependent that has no transformer * associated * @param dependent The dependent that didn't have a transformer */ error NoTransformerRegistered(address dependent); /** * @notice Emitted when new dependents are registered * @param registrations The dependents that were registered */ event TransformersRegistered(TransformerRegistration[] registrations); /** * @notice Emitted when dependents are removed from the registry * @param dependents The dependents that were removed */ event TransformersRemoved(address[] dependents); /** * @notice Returns the registered transformer for the given dependents * @param dependents The dependents to get the transformer for * @return The registered transformers, or the zero address if there isn't any */ function transformers(address[] calldata dependents) external view returns (ITransformer[] memory); /** * @notice Sets a new registration for the given dependents * @dev Can only be called by admin * @param registrations The associations to register */ function registerTransformers(TransformerRegistration[] calldata registrations) external; /** * @notice Removes registration for the given dependents * @dev Can only be called by admin * @param dependents The associations to remove */ function removeTransformers(address[] calldata dependents) external; /** * @notice Executes a transformation to the underlying tokens, by taking the caller's entire * dependent balance. This is meant to be used as part of a multi-hop swap * @dev This function was made payable, so that it could be multicalled when msg.value > 0 * @param dependent The address of the dependent token * @param recipient The address that would receive the underlying tokens * @param minAmountOut The minimum amount of underlying that the caller expects to get. Will fail * if less is received. As a general rule, the underlying tokens should * be provided in the same order as `getUnderlying` returns them * @param deadline A deadline when the transaction becomes invalid * @return The transformed amount in each of the underlying tokens */ function transformAllToUnderlying( address dependent, address recipient, UnderlyingAmount[] calldata minAmountOut, uint256 deadline ) external payable returns (UnderlyingAmount[] memory); /** * @notice Executes a transformation to the dependent token, by taking the caller's entire * underlying balance. This is meant to be used as part of a multi-hop swap * @dev This function will not work when the underlying token is ETH/MATIC/BNB, since it can't be taken from the caller * This function was made payable, so that it could be multicalled when msg.value > 0 * @param dependent The address of the dependent token * @param recipient The address that would receive the dependent tokens * @param minAmountOut The minimum amount of dependent that the caller expects to get. Will fail * if less is received * @param deadline A deadline when the transaction becomes invalid * @return amountDependent The transformed amount in the dependent token */ function transformAllToDependent( address dependent, address recipient, uint256 minAmountOut, uint256 deadline ) external payable returns (uint256 amountDependent); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /** * @title A contract that can map between one token and their underlying counterparts, and vice-versa * @notice This contract defines the concept of dependent tokens. These are tokens that depend on one or more underlying tokens, * they can't exist on their own. This concept can apply to some known types of tokens, such as: * - Wrappers (WETH/WMATIC/WBNB) * - ERC-4626 tokens * - LP tokens * Now, transformers are smart contract that knows how to map dependent tokens into their underlying counterparts, * and vice-versa. We are doing this so that we can abstract the way tokens can be transformed between each other * @dev All non-view functions were made payable, so that they could be multicalled when msg.value > 0 */ interface ITransformer { /// @notice An amount of an underlying token struct UnderlyingAmount { address underlying; uint256 amount; } /// @notice Thrown when the underlying input is not valid for the used transformer error InvalidUnderlyingInput(); /// @notice Thrown when the transformation provides less output than expected error ReceivedLessThanExpected(uint256 received); /// @notice Thrown when the transformation needs more input than expected error NeededMoreThanExpected(uint256 needed); /// @notice Thrown when a transaction is executed after the deadline has passed error TransactionExpired(); /** * @notice Returns the addresses of all the underlying tokens, for the given dependent * @dev This function must be unaware of context. The returned values must be the same, * regardless of who the caller is * @param dependent The address of the dependent token * @return The addresses of all the underlying tokens */ function getUnderlying(address dependent) external view returns (address[] memory); /** * @notice Calculates how much would the transformation to the underlying tokens return * @dev This function must be unaware of context. The returned values must be the same, * regardless of who the caller is * @param dependent The address of the dependent token * @param amountDependent The amount to transform * @return The transformed amount in each of the underlying tokens */ function calculateTransformToUnderlying(address dependent, uint256 amountDependent) external view returns (UnderlyingAmount[] memory); /** * @notice Calculates how much would the transformation to the dependent token return * @dev This function must be unaware of context. The returned values must be the same, * regardless of who the caller is * @param dependent The address of the dependent token * @param underlying The amounts of underlying tokens to transform * @return amountDependent The transformed amount in the dependent token */ function calculateTransformToDependent(address dependent, UnderlyingAmount[] calldata underlying) external view returns (uint256 amountDependent); /** * @notice Calculates how many dependent tokens are needed to transform to the expected * amount of underlying * @dev This function must be unaware of context. The returned values must be the same, * regardless of who the caller is * @param dependent The address of the dependent token * @param expectedUnderlying The expected amounts of underlying tokens * @return neededDependent The amount of dependent needed */ function calculateNeededToTransformToUnderlying(address dependent, UnderlyingAmount[] calldata expectedUnderlying) external view returns (uint256 neededDependent); /** * @notice Calculates how many underlying tokens are needed to transform to the expected * amount of dependent * @dev This function must be unaware of context. The returned values must be the same, * regardless of who the caller is * @param dependent The address of the dependent token * @param expectedDependent The expected amount of dependent tokens * @return neededUnderlying The amount of underlying tokens needed */ function calculateNeededToTransformToDependent(address dependent, uint256 expectedDependent) external view returns (UnderlyingAmount[] memory neededUnderlying); /** * @notice Executes the transformation to the underlying tokens * @param dependent The address of the dependent token * @param amountDependent The amount to transform * @param recipient The address that would receive the underlying tokens * @param minAmountOut The minimum amount of underlying that the caller expects to get. Will fail * if less is received. As a general rule, the underlying tokens should * be provided in the same order as `getUnderlying` returns them * @param deadline A deadline when the transaction becomes invalid * @return The transformed amount in each of the underlying tokens */ function transformToUnderlying( address dependent, uint256 amountDependent, address recipient, UnderlyingAmount[] calldata minAmountOut, uint256 deadline ) external payable returns (UnderlyingAmount[] memory); /** * @notice Executes the transformation to the dependent token * @param dependent The address of the dependent token * @param underlying The amounts of underlying tokens to transform * @param recipient The address that would receive the dependent tokens * @param minAmountOut The minimum amount of dependent that the caller expects to get. Will fail * if less is received * @param deadline A deadline when the transaction becomes invalid * @return amountDependent The transformed amount in the dependent token */ function transformToDependent( address dependent, UnderlyingAmount[] calldata underlying, address recipient, uint256 minAmountOut, uint256 deadline ) external payable returns (uint256 amountDependent); /** * @notice Transforms dependent tokens to an expected amount of underlying tokens * @param dependent The address of the dependent token * @param expectedUnderlying The expected amounts of underlying tokens * @param recipient The address that would receive the underlying tokens * @param maxAmountIn The maximum amount of dependent that the caller is willing to spend. * Will fail more is needed * @param deadline A deadline when the transaction becomes invalid * @return spentDependent The amount of spent dependent tokens */ function transformToExpectedUnderlying( address dependent, UnderlyingAmount[] calldata expectedUnderlying, address recipient, uint256 maxAmountIn, uint256 deadline ) external payable returns (uint256 spentDependent); /** * @notice Transforms underlying tokens to an expected amount of dependent tokens * @param dependent The address of the dependent token * @param expectedDependent The expected amounts of dependent tokens * @param recipient The address that would receive the underlying tokens * @param maxAmountIn The maximum amount of underlying that the caller is willing to spend. * Will fail more is needed. As a general rule, the underlying tokens should * be provided in the same order as `getUnderlying` returns them * @param deadline A deadline when the transaction becomes invalid * @return spentUnderlying The amount of spent underlying tokens */ function transformToExpectedDependent( address dependent, uint256 expectedDependent, address recipient, UnderlyingAmount[] calldata maxAmountIn, uint256 deadline ) external payable returns (UnderlyingAmount[] memory spentUnderlying); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.7 <0.9.0; import '@openzeppelin/contracts/interfaces/IERC20.sol'; import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import '@openzeppelin/contracts/utils/Address.sol'; import '../../interfaces/utils/ICollectableDust.sol'; import './Governable.sol'; abstract contract CollectableDust is Governable, ICollectableDust { using SafeERC20 for IERC20; using Address for address payable; /// @inheritdoc ICollectableDust address public constant PROTOCOL_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; /// @inheritdoc ICollectableDust function getBalances(address[] calldata _tokens) external view returns (TokenBalance[] memory _balances) { _balances = new TokenBalance[](_tokens.length); for (uint256 i; i < _tokens.length; i++) { uint256 _balance = _tokens[i] == PROTOCOL_TOKEN ? address(this).balance : IERC20(_tokens[i]).balanceOf(address(this)); _balances[i] = TokenBalance({token: _tokens[i], balance: _balance}); } } /// @inheritdoc ICollectableDust function sendDust( address _token, uint256 _amount, address _recipient ) external onlyGovernor { if (_recipient == address(0)) revert DustRecipientIsZeroAddress(); if (_token == PROTOCOL_TOKEN) { payable(_recipient).sendValue(_amount); } else { IERC20(_token).safeTransfer(_recipient, _amount); } emit DustSent(_token, _amount, _recipient); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.7 <0.9.0; import '@openzeppelin/contracts/utils/Address.sol'; import '../../interfaces/utils/IMulticall.sol'; /** * @dev Adding this contract will enable batching calls. This is basically the same as Open Zeppelin's * Multicall contract, but we have made it payable. Any contract that uses this Multicall version * should be very careful when using msg.value. * For more context, read: https://github.com/Uniswap/v3-periphery/issues/52 */ abstract contract Multicall is IMulticall { /// @inheritdoc IMulticall function multicall(bytes[] calldata data) external payable returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i; i < data.length; i++) { results[i] = Address.functionDelegateCall(address(this), data[i]); } return results; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; 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 Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _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) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ 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"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.7 <0.9.0; import './IGovernable.sol'; /** * @title A contract that allows the current governor to withdraw funds * @notice This is meant to be used to recover any tokens that were sent to the contract * by mistake */ interface ICollectableDust { /// @notice The balance of a given token struct TokenBalance { address token; uint256 balance; } /// @notice Thrown when trying to send dust to the zero address error DustRecipientIsZeroAddress(); /** * @notice Emitted when dust is sent * @param token The token that was sent * @param amount The amount that was sent * @param recipient The address that received the tokens */ event DustSent(address token, uint256 amount, address recipient); /** * @notice Returns the address of the protocol token * @dev Cannot be modified * @return The address of the protocol token; */ function PROTOCOL_TOKEN() external view returns (address); /** * @notice Returns the balance of each of the given tokens * @dev Meant to be used for off-chain queries * @param tokens The tokens to check the balance for, can be ERC20s or the protocol token * @return The balances for the given tokens */ function getBalances(address[] calldata tokens) external view returns (TokenBalance[] memory); /** * @notice Sends the given token to the recipient * @dev Can only be called by the governor * @param token The token to send to the recipient (can be an ERC20 or the protocol token) * @param amount The amount to transfer to the recipient * @param recipient The address of the recipient */ function sendDust( address token, uint256 amount, address recipient ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.7 <0.9.0; import '../../interfaces/utils/IGovernable.sol'; /** * @notice This contract is meant to be used in other contracts. By using this contract, * a specific address will be given a "governor" role, which basically will be able to * control certains aspects of the contract. There are other contracts that do the same, * but this contract forces a new governor to accept the role before it's transferred. * This is a basically a safety measure to prevent losing access to the contract. */ abstract contract Governable is IGovernable { /// @inheritdoc IGovernable address public governor; /// @inheritdoc IGovernable address public pendingGovernor; constructor(address _governor) { if (_governor == address(0)) revert GovernorIsZeroAddress(); governor = _governor; } /// @inheritdoc IGovernable function isGovernor(address _account) public view returns (bool) { return _account == governor; } /// @inheritdoc IGovernable function isPendingGovernor(address _account) public view returns (bool) { return _account == pendingGovernor; } /// @inheritdoc IGovernable function setPendingGovernor(address _pendingGovernor) external onlyGovernor { pendingGovernor = _pendingGovernor; emit PendingGovernorSet(_pendingGovernor); } /// @inheritdoc IGovernable function acceptPendingGovernor() external onlyPendingGovernor { governor = pendingGovernor; pendingGovernor = address(0); emit PendingGovernorAccepted(); } modifier onlyGovernor() { if (!isGovernor(msg.sender)) revert OnlyGovernor(); _; } modifier onlyPendingGovernor() { if (!isPendingGovernor(msg.sender)) revert OnlyPendingGovernor(); _; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.7 <0.9.0; /** * @title A contract that manages a "governor" role */ interface IGovernable { /// @notice Thrown when trying to set the zero address as governor error GovernorIsZeroAddress(); /// @notice Thrown when trying to execute an action that only the governor an execute error OnlyGovernor(); /// @notice Thrown when trying to execute an action that only the pending governor an execute error OnlyPendingGovernor(); /** * @notice Emitted when a new pending governor is set * @param newPendingGovernor The new pending governor */ event PendingGovernorSet(address newPendingGovernor); /** * @notice Emitted when the pending governor accepts the role and becomes the governor */ event PendingGovernorAccepted(); /** * @notice Returns the address of the governor * @return The address of the governor */ function governor() external view returns (address); /** * @notice Returns the address of the pending governor * @return The address of the pending governor */ function pendingGovernor() external view returns (address); /** * @notice Returns whether the given account is the current governor * @param account The account to check * @return Whether it is the current governor or not */ function isGovernor(address account) external view returns (bool); /** * @notice Returns whether the given account is the pending governor * @param account The account to check * @return Whether it is the pending governor or not */ function isPendingGovernor(address account) external view returns (bool); /** * @notice Sets a new pending governor * @dev Only the current governor can execute this action * @param pendingGovernor The new pending governor */ function setPendingGovernor(address pendingGovernor) external; /** * @notice Sets the pending governor as the governor * @dev Only the pending governor can execute this action */ function acceptPendingGovernor() external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.7 <0.9.0; /** * @title A contract that supports batching calls * @notice Contracts with this interface provide a function to batch together multiple calls * in a single external call. */ interface IMulticall { /** * @notice Receives and executes a batch of function calls on this contract. * @param data A list of different function calls to execute * @return results The result of executing each of those calls */ function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); }
{ "optimizer": { "enabled": true, "runs": 9999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_governor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressIsNotTransformer","type":"error"},{"inputs":[],"name":"DustRecipientIsZeroAddress","type":"error"},{"inputs":[],"name":"GovernorIsZeroAddress","type":"error"},{"inputs":[],"name":"InvalidUnderlyingInput","type":"error"},{"inputs":[{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"NeededMoreThanExpected","type":"error"},{"inputs":[{"internalType":"address","name":"dependent","type":"address"}],"name":"NoTransformerRegistered","type":"error"},{"inputs":[],"name":"OnlyGovernor","type":"error"},{"inputs":[],"name":"OnlyPendingGovernor","type":"error"},{"inputs":[{"internalType":"uint256","name":"received","type":"uint256"}],"name":"ReceivedLessThanExpected","type":"error"},{"inputs":[],"name":"TransactionExpired","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"}],"name":"DustSent","type":"event"},{"anonymous":false,"inputs":[],"name":"PendingGovernorAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newPendingGovernor","type":"address"}],"name":"PendingGovernorSet","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"transformer","type":"address"},{"internalType":"address[]","name":"dependents","type":"address[]"}],"indexed":false,"internalType":"struct ITransformerRegistry.TransformerRegistration[]","name":"registrations","type":"tuple[]"}],"name":"TransformersRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"dependents","type":"address[]"}],"name":"TransformersRemoved","type":"event"},{"inputs":[],"name":"PROTOCOL_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptPendingGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dependent","type":"address"},{"internalType":"uint256","name":"_expectedDependent","type":"uint256"}],"name":"calculateNeededToTransformToDependent","outputs":[{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"_neededUnderlying","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dependent","type":"address"},{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"_expectedUnderlying","type":"tuple[]"}],"name":"calculateNeededToTransformToUnderlying","outputs":[{"internalType":"uint256","name":"_neededDependent","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dependent","type":"address"},{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"_underlying","type":"tuple[]"}],"name":"calculateTransformToDependent","outputs":[{"internalType":"uint256","name":"_amountDependent","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dependent","type":"address"},{"internalType":"uint256","name":"_amountDependent","type":"uint256"}],"name":"calculateTransformToUnderlying","outputs":[{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"getBalances","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"}],"internalType":"struct ICollectableDust.TokenBalance[]","name":"_balances","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dependent","type":"address"}],"name":"getUnderlying","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isGovernor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isPendingGovernor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"pendingGovernor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"transformer","type":"address"},{"internalType":"address[]","name":"dependents","type":"address[]"}],"internalType":"struct ITransformerRegistry.TransformerRegistration[]","name":"_registrations","type":"tuple[]"}],"name":"registerTransformers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_dependents","type":"address[]"}],"name":"removeTransformers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"sendDust","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pendingGovernor","type":"address"}],"name":"setPendingGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dependent","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_minAmountOut","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"transformAllToDependent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_dependent","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"_minAmountOut","type":"tuple[]"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"transformAllToUnderlying","outputs":[{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_dependent","type":"address"},{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"_underlying","type":"tuple[]"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_minAmountOut","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"transformToDependent","outputs":[{"internalType":"uint256","name":"_amountDependent","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_dependent","type":"address"},{"internalType":"uint256","name":"_expectedDependent","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"},{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"_maxAmountIn","type":"tuple[]"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"transformToExpectedDependent","outputs":[{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"_spentUnderlying","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_dependent","type":"address"},{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"_expectedUnderlying","type":"tuple[]"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_maxAmountIn","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"transformToExpectedUnderlying","outputs":[{"internalType":"uint256","name":"_spentDependent","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_dependent","type":"address"},{"internalType":"uint256","name":"_amountDependent","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"},{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"_minAmountOut","type":"tuple[]"},{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"transformToUnderlying","outputs":[{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ITransformer.UnderlyingAmount[]","name":"","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_dependents","type":"address[]"}],"name":"transformers","outputs":[{"internalType":"contract ITransformer[]","name":"_transformers","type":"address[]"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162002cf438038062002cf4833981016040819052620000349162000084565b806001600160a01b0381166200005d5760405163e6250e3360e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b039290921691909117905550620000b6565b6000602082840312156200009757600080fd5b81516001600160a01b0381168114620000af57600080fd5b9392505050565b612c2e80620000c66000396000f3fe60806040526004361061019a5760003560e01c80634f899c48116100e1578063df08aed51161008a578063e714729411610064578063e714729414610491578063edfb1b2b146104a4578063f0dbc0f2146104c4578063f235757f146104d757600080fd5b8063df08aed514610413578063e3056a3414610442578063e43581b81461046257600080fd5b8063966abd00116100bb578063966abd00146103b3578063a1e8b1d5146103d3578063ac9650d8146103f357600080fd5b80634f899c481461034b578063585cc6a51461036b5780638b7e506e1461039357600080fd5b80632426c682116101435780633142085c1161011d5780633142085c146102f8578063451fcf4c1461030b5780634e89a7111461031e57600080fd5b80632426c6821461028a5780632d2ae1c11461029d5780632d540300146102ca57600080fd5b80630c340a24116101745780630c340a241461022a57806313f6986d146102625780631bbae98a1461027757600080fd5b806301ffc9a7146101a657806309a33a9e146101db5780630a8355b6146101fd57600080fd5b366101a157005b600080fd5b3480156101b257600080fd5b506101c66101c1366004611e7a565b6104f7565b60405190151581526020015b60405180910390f35b3480156101e757600080fd5b506101fb6101f6366004611f08565b610674565b005b34801561020957600080fd5b5061021d610218366004611f62565b610789565b6040516101d29190611fe6565b34801561023657600080fd5b5060005461024a906001600160a01b031681565b6040516001600160a01b0390911681526020016101d2565b34801561026e57600080fd5b506101fb610831565b61021d6102853660046120a6565b6108dd565b61021d6102983660046121db565b610a20565b3480156102a957600080fd5b506102bd6102b8366004611f08565b610a7b565b6040516101d29190612256565b3480156102d657600080fd5b506102ea6102e53660046122b6565b610c64565b6040519081526020016101d2565b61021d6103063660046121db565b610d08565b6102ea61031936600461230b565b610d40565b34801561032a57600080fd5b5061033e610339366004612385565b610d8d565b6040516101d291906123a2565b34801561035757600080fd5b506102ea6103663660046122b6565b610e25565b34801561037757600080fd5b5061024a73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b34801561039f57600080fd5b506101fb6103ae366004611f08565b610e7d565b3480156103bf57600080fd5b506101fb6103ce3660046123ef565b61104f565b3480156103df57600080fd5b5061021d6103ee366004611f62565b61117e565b610406610401366004611f08565b6111dd565b6040516101d29190612481565b34801561041f57600080fd5b506101c661042e366004612385565b6001546001600160a01b0391821691161490565b34801561044e57600080fd5b5060015461024a906001600160a01b031681565b34801561046e57600080fd5b506101c661047d366004612385565b6000546001600160a01b0391821691161490565b6102ea61049f36600461230b565b6112cb565b3480156104b057600080fd5b5061033e6104bf366004611f08565b611302565b6102ea6104d2366004612501565b6113dc565b3480156104e357600080fd5b506101fb6104f2366004612385565b611636565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f3050af3c00000000000000000000000000000000000000000000000000000000148061058a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f35cfa26f00000000000000000000000000000000000000000000000000000000145b806105d657507fffffffff0000000000000000000000000000000000000000000000000000000082167fe31c9a6400000000000000000000000000000000000000000000000000000000145b8061062257507fffffffff0000000000000000000000000000000000000000000000000000000082167fac9650d800000000000000000000000000000000000000000000000000000000145b8061066e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000546001600160a01b031633146106b8576040517fe0a8b92000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8181101561074b576000600260008585858181106106db576106db612547565b90506020020160208101906106f09190612385565b6001600160a01b039081168252602082019290925260400160002080547fffffffffffffffffffffffff000000000000000000000000000000000000000016929091169190911790558061074381612576565b9150506106bb565b507f225e6da07f4b15ff2871c993c2ba64a3203cc1094dda4fc8239b21f100eb01fc828260405161077d929190612613565b60405180910390a15050565b60606000610796846116e6565b6040517f0a8355b60000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301526024820186905291925090821690630a8355b6906044015b600060405180830381865afa158015610801573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108299190810190612627565b949350505050565b6001546001600160a01b03163314610875576040517f9ba0305d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018054600080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081166001600160a01b0384161782559091169091556040517fdc57ca23c46d823853915ed5a090ca0ee9db5eb6a46f5c58e1c9158de861fd769190a1565b606060006108ea866116e6565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529091506000906001600160a01b038816906370a0823190602401602060405180830381865afa15801561094d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097191906126db565b905060006109fe83632426c68260e01b8a858b8b8b60405160240161099a9594939291906126f4565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611748565b905080806020019051810190610a149190612627565b98975050505050505050565b60606000610a2d886116e6565b90506000610a5882632426c68260e01b8b8b8b8b8b8b60405160240161099a96959493929190612780565b905080806020019051810190610a6e9190612627565b9998505050505050505050565b60608167ffffffffffffffff811115610a9657610a96611ff9565b604051908082528060200260200182016040528015610adb57816020015b6040805180820190915260008082526020820152815260200190600190039081610ab45790505b50905060005b82811015610c5d57600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee858584818110610b1257610b12612547565b9050602002016020810190610b279190612385565b6001600160a01b031614610be457848483818110610b4757610b47612547565b9050602002016020810190610b5c9190612385565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdf91906126db565b610be6565b475b90506040518060400160405280868685818110610c0557610c05612547565b9050602002016020810190610c1a9190612385565b6001600160a01b0316815260200182815250838381518110610c3e57610c3e612547565b6020026020010181905250508080610c5590612576565b915050610ae1565b5092915050565b600080610c70856116e6565b6040517f2d5403000000000000000000000000000000000000000000000000000000000081529091506001600160a01b03821690632d54030090610cbc908890889088906004016127c6565b602060405180830381865afa158015610cd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfd91906126db565b9150505b9392505050565b60606000610d15886116e6565b90506000610a5882633142085c60e01b8b8b8b8b8b8b60405160240161099a96959493929190612780565b600080610d4c886116e6565b90506000610d778263451fcf4c60e01b8b8b8b8b8b8b60405160240161099a969594939291906127f2565b905080806020019051810190610a6e91906126db565b60606000610d9a836116e6565b6040517f4e89a7110000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015291925090821690634e89a71190602401600060405180830381865afa158015610dfd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d019190810190612833565b600080610e31856116e6565b6040517f4f899c480000000000000000000000000000000000000000000000000000000081529091506001600160a01b03821690634f899c4890610cbc908890889088906004016127c6565b6000546001600160a01b03163314610ec1576040517fe0a8b92000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8181101561101d576000838383818110610ee057610ee0612547565b9050602002810190610ef291906128c2565b610efb90612900565b90506000610f2d82600001517f3050af3c00000000000000000000000000000000000000000000000000000000611754565b905080610f795781516040517f6937be1e0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024015b60405180910390fd5b60005b8260200151518110156110075782600001516002600085602001518481518110610fa857610fa8612547565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508080610fff90612576565b915050610f7c565b505050808061101590612576565b915050610ec4565b507f31aa6341dae4dcd30a25fce577c3247b9821f8577a51611725fabe18391ca247828260405161077d9291906129b8565b6000546001600160a01b03163314611093576040517fe0a8b92000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166110d3576040517f517f842200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff11111111111111111111111111111111111111126001600160a01b0384160161111b576111166001600160a01b03821683611770565b61112f565b61112f6001600160a01b03841682846118c2565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6060600061118b846116e6565b6040517fa1e8b1d50000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152602482018690529192509082169063a1e8b1d5906044016107e4565b60608167ffffffffffffffff8111156111f8576111f8611ff9565b60405190808252806020026020018201604052801561122b57816020015b60608152602001906001900390816112165790505b50905060005b82811015610c5d5761129b3085858481811061124f5761124f612547565b90506020028101906112619190612ae6565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061194292505050565b8282815181106112ad576112ad612547565b602002602001018190525080806112c390612576565b915050611231565b6000806112d7886116e6565b90506000610d778263e714729460e01b8b8b8b8b8b8b60405160240161099a969594939291906127f2565b60608167ffffffffffffffff81111561131d5761131d611ff9565b604051908082528060200260200182016040528015611346578160200160208202803683370190505b50905060005b82811015610c5d576002600085858481811061136a5761136a612547565b905060200201602081019061137f9190612385565b6001600160a01b03908116825260208201929092526040016000205483519116908390839081106113b2576113b2612547565b6001600160a01b0390921660209283029190910190910152806113d481612576565b91505061134c565b6000806113e8866116e6565b6040517f4e89a7110000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152919250600091831690634e89a71190602401600060405180830381865afa15801561144d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114759190810190612833565b90506000815167ffffffffffffffff81111561149357611493611ff9565b6040519080825280602002602001820160405280156114d857816020015b60408051808201909152600080825260208201528152602001906001900390816114b15790505b50905060005b825181101561160e5760008382815181106114fb576114fb612547565b60200260200101519050600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0316826001600160a01b0316146115ba576040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015611591573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b591906126db565b6115bc565b475b90506040518060400160405280836001600160a01b03168152602001828152508484815181106115ee576115ee612547565b60200260200101819052505050808061160690612576565b9150506114de565b506000610d778463451fcf4c60e01b8b858c8c8c60405160240161099a959493929190612b4b565b6000546001600160a01b0316331461167a576040517fe0a8b92000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f56bddfa0cee9697cebddf9acd7f23dc6583663b05e007b877056d05017994def9060200160405180910390a150565b6001600160a01b038082166000908152600260205260409020541680611743576040517f4f0f43260000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610f70565b919050565b6060610d018383611942565b600061175f83611967565b8015610d015750610d0183836119cb565b804710156117da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610f70565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611827576040519150601f19603f3d011682016040523d82523d6000602084013e61182c565b606091505b50509050806118bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610f70565b505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526118bd908490611a9a565b6060610d018383604051806060016040528060278152602001612bd260279139611b99565b6000611993827f01ffc9a7000000000000000000000000000000000000000000000000000000006119cb565b801561066e57506119c4827fffffffff000000000000000000000000000000000000000000000000000000006119cb565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015611a83575060208210155b8015611a8f5750600081115b979650505050505050565b6000611aef826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611ca79092919063ffffffff16565b8051909150156118bd5780806020019051810190611b0d9190612b8a565b6118bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610f70565b60606001600160a01b0384163b611c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152608401610f70565b600080856001600160a01b031685604051611c4d9190612bac565b600060405180830381855af49150503d8060008114611c88576040519150601f19603f3d011682016040523d82523d6000602084013e611c8d565b606091505b5091509150611c9d828286611cb6565b9695505050505050565b60606108298484600085611d09565b60608315611cc5575081610d01565b825115611cd55782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f709190612bbe565b606082471015611d9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610f70565b6001600160a01b0385163b611e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f70565b600080866001600160a01b03168587604051611e289190612bac565b60006040518083038185875af1925050503d8060008114611e65576040519150601f19603f3d011682016040523d82523d6000602084013e611e6a565b606091505b5091509150611a8f828286611cb6565b600060208284031215611e8c57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610d0157600080fd5b60008083601f840112611ece57600080fd5b50813567ffffffffffffffff811115611ee657600080fd5b6020830191508360208260051b8501011115611f0157600080fd5b9250929050565b60008060208385031215611f1b57600080fd5b823567ffffffffffffffff811115611f3257600080fd5b611f3e85828601611ebc565b90969095509350505050565b6001600160a01b0381168114611f5f57600080fd5b50565b60008060408385031215611f7557600080fd5b8235611f8081611f4a565b946020939093013593505050565b600081518084526020808501945080840160005b83811015611fdb57611fc887835180516001600160a01b03168252602090810151910152565b6040969096019590820190600101611fa2565b509495945050505050565b602081526000610d016020830184611f8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561204b5761204b611ff9565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561207a5761207a611ff9565b604052919050565b600067ffffffffffffffff82111561209c5761209c611ff9565b5060051b60200190565b600080600080608085870312156120bc57600080fd5b84356120c781611f4a565b93506020858101356120d881611f4a565b935060408681013567ffffffffffffffff8111156120f557600080fd5b8701601f8101891361210657600080fd5b803561211961211482612082565b612051565b81815260069190911b8201840190848101908b83111561213857600080fd5b928501925b828410156121815784848d0312156121555760008081fd5b61215d612028565b843561216881611f4a565b815284870135878201528252928401929085019061213d565b989b979a509798606001359750505050505050565b60008083601f8401126121a857600080fd5b50813567ffffffffffffffff8111156121c057600080fd5b6020830191508360208260061b8501011115611f0157600080fd5b60008060008060008060a087890312156121f457600080fd5b86356121ff81611f4a565b955060208701359450604087013561221681611f4a565b9350606087013567ffffffffffffffff81111561223257600080fd5b61223e89828a01612196565b979a9699509497949695608090950135949350505050565b602080825282518282018190526000919060409081850190868401855b828110156122a95761229984835180516001600160a01b03168252602090810151910152565b9284019290850190600101612273565b5091979650505050505050565b6000806000604084860312156122cb57600080fd5b83356122d681611f4a565b9250602084013567ffffffffffffffff8111156122f257600080fd5b6122fe86828701612196565b9497909650939450505050565b60008060008060008060a0878903121561232457600080fd5b863561232f81611f4a565b9550602087013567ffffffffffffffff81111561234b57600080fd5b61235789828a01612196565b909650945050604087013561236b81611f4a565b959894975092956060810135946080909101359350915050565b60006020828403121561239757600080fd5b8135610d0181611f4a565b6020808252825182820181905260009190848201906040850190845b818110156123e35783516001600160a01b0316835292840192918401916001016123be565b50909695505050505050565b60008060006060848603121561240457600080fd5b833561240f81611f4a565b925060208401359150604084013561242681611f4a565b809150509250925092565b60005b8381101561244c578181015183820152602001612434565b50506000910152565b6000815180845261246d816020860160208601612431565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156124f4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526124e2858351612455565b945092850192908501906001016124a8565b5092979650505050505050565b6000806000806080858703121561251757600080fd5b843561252281611f4a565b9350602085013561253281611f4a565b93969395505050506040820135916060013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036125ce577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b8183526000602080850194508260005b85811015611fdb5781356125f881611f4a565b6001600160a01b0316875295820195908201906001016125e5565b6020815260006108296020830184866125d5565b6000602080838503121561263a57600080fd5b825167ffffffffffffffff81111561265157600080fd5b8301601f8101851361266257600080fd5b805161267061211482612082565b81815260069190911b8201830190838101908783111561268f57600080fd5b928401925b82841015611a8f57604084890312156126ad5760008081fd5b6126b5612028565b84516126c081611f4a565b81528486015186820152825260409093019290840190612694565b6000602082840312156126ed57600080fd5b5051919050565b60006001600160a01b03808816835286602084015280861660408401525060a0606083015261272660a0830185611f8e565b90508260808301529695505050505050565b8183526000602080850194508260005b85811015611fdb57813561275b81611f4a565b6001600160a01b03168752818301358388015260409687019690910190600101612748565b60006001600160a01b03808916835287602084015280871660408401525060a060608301526127b360a083018587612738565b9050826080830152979650505050505050565b6001600160a01b03841681526040602082015260006127e9604083018486612738565b95945050505050565b60006001600160a01b03808916835260a0602084015261281660a08401888a612738565b951660408301525060608101929092526080909101529392505050565b6000602080838503121561284657600080fd5b825167ffffffffffffffff81111561285d57600080fd5b8301601f8101851361286e57600080fd5b805161287c61211482612082565b81815260059190911b8201830190838101908783111561289b57600080fd5b928401925b82841015611a8f5783516128b381611f4a565b825292840192908401906128a0565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126128f657600080fd5b9190910192915050565b60006040823603121561291257600080fd5b61291a612028565b823561292581611f4a565b815260208381013567ffffffffffffffff81111561294257600080fd5b840136601f82011261295357600080fd5b803561296161211482612082565b81815260059190911b8201830190838101903683111561298057600080fd5b928401925b828410156129a757833561299881611f4a565b82529284019290840190612985565b938501939093525091949350505050565b60208082528181018390526000906040808401600586811b8601830188865b89811015612ad7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18c3603018112612a3857600080fd5b8b018035612a4581611f4a565b6001600160a01b0316845280880135368290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1018112612a8557600080fd5b01878101903567ffffffffffffffff811115612aa057600080fd5b80861b3603821315612ab157600080fd5b8789860152612ac388860182846125d5565b9689019694505050908601906001016129d7565b50909998505050505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612b1b57600080fd5b83018035915067ffffffffffffffff821115612b3657600080fd5b602001915036819003821315611f0157600080fd5b60006001600160a01b03808816835260a06020840152612b6e60a0840188611f8e565b9516604083015250606081019290925260809091015292915050565b600060208284031215612b9c57600080fd5b81518015158114610d0157600080fd5b600082516128f6818460208701612431565b602081526000610d01602083018461245556fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220cc266475ce423350cff3765cc33e03fce925157146b6ba892861e1309edcee9e64736f6c63430008100033000000000000000000000000ec864be26084ba3bbf3caacf8f6961a9263319c4
Deployed Bytecode
0x60806040526004361061019a5760003560e01c80634f899c48116100e1578063df08aed51161008a578063e714729411610064578063e714729414610491578063edfb1b2b146104a4578063f0dbc0f2146104c4578063f235757f146104d757600080fd5b8063df08aed514610413578063e3056a3414610442578063e43581b81461046257600080fd5b8063966abd00116100bb578063966abd00146103b3578063a1e8b1d5146103d3578063ac9650d8146103f357600080fd5b80634f899c481461034b578063585cc6a51461036b5780638b7e506e1461039357600080fd5b80632426c682116101435780633142085c1161011d5780633142085c146102f8578063451fcf4c1461030b5780634e89a7111461031e57600080fd5b80632426c6821461028a5780632d2ae1c11461029d5780632d540300146102ca57600080fd5b80630c340a24116101745780630c340a241461022a57806313f6986d146102625780631bbae98a1461027757600080fd5b806301ffc9a7146101a657806309a33a9e146101db5780630a8355b6146101fd57600080fd5b366101a157005b600080fd5b3480156101b257600080fd5b506101c66101c1366004611e7a565b6104f7565b60405190151581526020015b60405180910390f35b3480156101e757600080fd5b506101fb6101f6366004611f08565b610674565b005b34801561020957600080fd5b5061021d610218366004611f62565b610789565b6040516101d29190611fe6565b34801561023657600080fd5b5060005461024a906001600160a01b031681565b6040516001600160a01b0390911681526020016101d2565b34801561026e57600080fd5b506101fb610831565b61021d6102853660046120a6565b6108dd565b61021d6102983660046121db565b610a20565b3480156102a957600080fd5b506102bd6102b8366004611f08565b610a7b565b6040516101d29190612256565b3480156102d657600080fd5b506102ea6102e53660046122b6565b610c64565b6040519081526020016101d2565b61021d6103063660046121db565b610d08565b6102ea61031936600461230b565b610d40565b34801561032a57600080fd5b5061033e610339366004612385565b610d8d565b6040516101d291906123a2565b34801561035757600080fd5b506102ea6103663660046122b6565b610e25565b34801561037757600080fd5b5061024a73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b34801561039f57600080fd5b506101fb6103ae366004611f08565b610e7d565b3480156103bf57600080fd5b506101fb6103ce3660046123ef565b61104f565b3480156103df57600080fd5b5061021d6103ee366004611f62565b61117e565b610406610401366004611f08565b6111dd565b6040516101d29190612481565b34801561041f57600080fd5b506101c661042e366004612385565b6001546001600160a01b0391821691161490565b34801561044e57600080fd5b5060015461024a906001600160a01b031681565b34801561046e57600080fd5b506101c661047d366004612385565b6000546001600160a01b0391821691161490565b6102ea61049f36600461230b565b6112cb565b3480156104b057600080fd5b5061033e6104bf366004611f08565b611302565b6102ea6104d2366004612501565b6113dc565b3480156104e357600080fd5b506101fb6104f2366004612385565b611636565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f3050af3c00000000000000000000000000000000000000000000000000000000148061058a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f35cfa26f00000000000000000000000000000000000000000000000000000000145b806105d657507fffffffff0000000000000000000000000000000000000000000000000000000082167fe31c9a6400000000000000000000000000000000000000000000000000000000145b8061062257507fffffffff0000000000000000000000000000000000000000000000000000000082167fac9650d800000000000000000000000000000000000000000000000000000000145b8061066e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000546001600160a01b031633146106b8576040517fe0a8b92000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8181101561074b576000600260008585858181106106db576106db612547565b90506020020160208101906106f09190612385565b6001600160a01b039081168252602082019290925260400160002080547fffffffffffffffffffffffff000000000000000000000000000000000000000016929091169190911790558061074381612576565b9150506106bb565b507f225e6da07f4b15ff2871c993c2ba64a3203cc1094dda4fc8239b21f100eb01fc828260405161077d929190612613565b60405180910390a15050565b60606000610796846116e6565b6040517f0a8355b60000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301526024820186905291925090821690630a8355b6906044015b600060405180830381865afa158015610801573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108299190810190612627565b949350505050565b6001546001600160a01b03163314610875576040517f9ba0305d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018054600080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081166001600160a01b0384161782559091169091556040517fdc57ca23c46d823853915ed5a090ca0ee9db5eb6a46f5c58e1c9158de861fd769190a1565b606060006108ea866116e6565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529091506000906001600160a01b038816906370a0823190602401602060405180830381865afa15801561094d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097191906126db565b905060006109fe83632426c68260e01b8a858b8b8b60405160240161099a9594939291906126f4565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611748565b905080806020019051810190610a149190612627565b98975050505050505050565b60606000610a2d886116e6565b90506000610a5882632426c68260e01b8b8b8b8b8b8b60405160240161099a96959493929190612780565b905080806020019051810190610a6e9190612627565b9998505050505050505050565b60608167ffffffffffffffff811115610a9657610a96611ff9565b604051908082528060200260200182016040528015610adb57816020015b6040805180820190915260008082526020820152815260200190600190039081610ab45790505b50905060005b82811015610c5d57600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee858584818110610b1257610b12612547565b9050602002016020810190610b279190612385565b6001600160a01b031614610be457848483818110610b4757610b47612547565b9050602002016020810190610b5c9190612385565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015610bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdf91906126db565b610be6565b475b90506040518060400160405280868685818110610c0557610c05612547565b9050602002016020810190610c1a9190612385565b6001600160a01b0316815260200182815250838381518110610c3e57610c3e612547565b6020026020010181905250508080610c5590612576565b915050610ae1565b5092915050565b600080610c70856116e6565b6040517f2d5403000000000000000000000000000000000000000000000000000000000081529091506001600160a01b03821690632d54030090610cbc908890889088906004016127c6565b602060405180830381865afa158015610cd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfd91906126db565b9150505b9392505050565b60606000610d15886116e6565b90506000610a5882633142085c60e01b8b8b8b8b8b8b60405160240161099a96959493929190612780565b600080610d4c886116e6565b90506000610d778263451fcf4c60e01b8b8b8b8b8b8b60405160240161099a969594939291906127f2565b905080806020019051810190610a6e91906126db565b60606000610d9a836116e6565b6040517f4e89a7110000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015291925090821690634e89a71190602401600060405180830381865afa158015610dfd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d019190810190612833565b600080610e31856116e6565b6040517f4f899c480000000000000000000000000000000000000000000000000000000081529091506001600160a01b03821690634f899c4890610cbc908890889088906004016127c6565b6000546001600160a01b03163314610ec1576040517fe0a8b92000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8181101561101d576000838383818110610ee057610ee0612547565b9050602002810190610ef291906128c2565b610efb90612900565b90506000610f2d82600001517f3050af3c00000000000000000000000000000000000000000000000000000000611754565b905080610f795781516040517f6937be1e0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024015b60405180910390fd5b60005b8260200151518110156110075782600001516002600085602001518481518110610fa857610fa8612547565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508080610fff90612576565b915050610f7c565b505050808061101590612576565b915050610ec4565b507f31aa6341dae4dcd30a25fce577c3247b9821f8577a51611725fabe18391ca247828260405161077d9291906129b8565b6000546001600160a01b03163314611093576040517fe0a8b92000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166110d3576040517f517f842200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff11111111111111111111111111111111111111126001600160a01b0384160161111b576111166001600160a01b03821683611770565b61112f565b61112f6001600160a01b03841682846118c2565b604080516001600160a01b0385811682526020820185905283168183015290517f9a3055ded8c8b5f21bbf4946c5afab6e1fa8b3f057922658e5e1ade125fb0b1e9181900360600190a1505050565b6060600061118b846116e6565b6040517fa1e8b1d50000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152602482018690529192509082169063a1e8b1d5906044016107e4565b60608167ffffffffffffffff8111156111f8576111f8611ff9565b60405190808252806020026020018201604052801561122b57816020015b60608152602001906001900390816112165790505b50905060005b82811015610c5d5761129b3085858481811061124f5761124f612547565b90506020028101906112619190612ae6565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061194292505050565b8282815181106112ad576112ad612547565b602002602001018190525080806112c390612576565b915050611231565b6000806112d7886116e6565b90506000610d778263e714729460e01b8b8b8b8b8b8b60405160240161099a969594939291906127f2565b60608167ffffffffffffffff81111561131d5761131d611ff9565b604051908082528060200260200182016040528015611346578160200160208202803683370190505b50905060005b82811015610c5d576002600085858481811061136a5761136a612547565b905060200201602081019061137f9190612385565b6001600160a01b03908116825260208201929092526040016000205483519116908390839081106113b2576113b2612547565b6001600160a01b0390921660209283029190910190910152806113d481612576565b91505061134c565b6000806113e8866116e6565b6040517f4e89a7110000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152919250600091831690634e89a71190602401600060405180830381865afa15801561144d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114759190810190612833565b90506000815167ffffffffffffffff81111561149357611493611ff9565b6040519080825280602002602001820160405280156114d857816020015b60408051808201909152600080825260208201528152602001906001900390816114b15790505b50905060005b825181101561160e5760008382815181106114fb576114fb612547565b60200260200101519050600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0316826001600160a01b0316146115ba576040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015611591573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b591906126db565b6115bc565b475b90506040518060400160405280836001600160a01b03168152602001828152508484815181106115ee576115ee612547565b60200260200101819052505050808061160690612576565b9150506114de565b506000610d778463451fcf4c60e01b8b858c8c8c60405160240161099a959493929190612b4b565b6000546001600160a01b0316331461167a576040517fe0a8b92000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f56bddfa0cee9697cebddf9acd7f23dc6583663b05e007b877056d05017994def9060200160405180910390a150565b6001600160a01b038082166000908152600260205260409020541680611743576040517f4f0f43260000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610f70565b919050565b6060610d018383611942565b600061175f83611967565b8015610d015750610d0183836119cb565b804710156117da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610f70565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611827576040519150601f19603f3d011682016040523d82523d6000602084013e61182c565b606091505b50509050806118bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610f70565b505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526118bd908490611a9a565b6060610d018383604051806060016040528060278152602001612bd260279139611b99565b6000611993827f01ffc9a7000000000000000000000000000000000000000000000000000000006119cb565b801561066e57506119c4827fffffffff000000000000000000000000000000000000000000000000000000006119cb565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015611a83575060208210155b8015611a8f5750600081115b979650505050505050565b6000611aef826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611ca79092919063ffffffff16565b8051909150156118bd5780806020019051810190611b0d9190612b8a565b6118bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610f70565b60606001600160a01b0384163b611c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152608401610f70565b600080856001600160a01b031685604051611c4d9190612bac565b600060405180830381855af49150503d8060008114611c88576040519150601f19603f3d011682016040523d82523d6000602084013e611c8d565b606091505b5091509150611c9d828286611cb6565b9695505050505050565b60606108298484600085611d09565b60608315611cc5575081610d01565b825115611cd55782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f709190612bbe565b606082471015611d9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610f70565b6001600160a01b0385163b611e0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f70565b600080866001600160a01b03168587604051611e289190612bac565b60006040518083038185875af1925050503d8060008114611e65576040519150601f19603f3d011682016040523d82523d6000602084013e611e6a565b606091505b5091509150611a8f828286611cb6565b600060208284031215611e8c57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610d0157600080fd5b60008083601f840112611ece57600080fd5b50813567ffffffffffffffff811115611ee657600080fd5b6020830191508360208260051b8501011115611f0157600080fd5b9250929050565b60008060208385031215611f1b57600080fd5b823567ffffffffffffffff811115611f3257600080fd5b611f3e85828601611ebc565b90969095509350505050565b6001600160a01b0381168114611f5f57600080fd5b50565b60008060408385031215611f7557600080fd5b8235611f8081611f4a565b946020939093013593505050565b600081518084526020808501945080840160005b83811015611fdb57611fc887835180516001600160a01b03168252602090810151910152565b6040969096019590820190600101611fa2565b509495945050505050565b602081526000610d016020830184611f8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561204b5761204b611ff9565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561207a5761207a611ff9565b604052919050565b600067ffffffffffffffff82111561209c5761209c611ff9565b5060051b60200190565b600080600080608085870312156120bc57600080fd5b84356120c781611f4a565b93506020858101356120d881611f4a565b935060408681013567ffffffffffffffff8111156120f557600080fd5b8701601f8101891361210657600080fd5b803561211961211482612082565b612051565b81815260069190911b8201840190848101908b83111561213857600080fd5b928501925b828410156121815784848d0312156121555760008081fd5b61215d612028565b843561216881611f4a565b815284870135878201528252928401929085019061213d565b989b979a509798606001359750505050505050565b60008083601f8401126121a857600080fd5b50813567ffffffffffffffff8111156121c057600080fd5b6020830191508360208260061b8501011115611f0157600080fd5b60008060008060008060a087890312156121f457600080fd5b86356121ff81611f4a565b955060208701359450604087013561221681611f4a565b9350606087013567ffffffffffffffff81111561223257600080fd5b61223e89828a01612196565b979a9699509497949695608090950135949350505050565b602080825282518282018190526000919060409081850190868401855b828110156122a95761229984835180516001600160a01b03168252602090810151910152565b9284019290850190600101612273565b5091979650505050505050565b6000806000604084860312156122cb57600080fd5b83356122d681611f4a565b9250602084013567ffffffffffffffff8111156122f257600080fd5b6122fe86828701612196565b9497909650939450505050565b60008060008060008060a0878903121561232457600080fd5b863561232f81611f4a565b9550602087013567ffffffffffffffff81111561234b57600080fd5b61235789828a01612196565b909650945050604087013561236b81611f4a565b959894975092956060810135946080909101359350915050565b60006020828403121561239757600080fd5b8135610d0181611f4a565b6020808252825182820181905260009190848201906040850190845b818110156123e35783516001600160a01b0316835292840192918401916001016123be565b50909695505050505050565b60008060006060848603121561240457600080fd5b833561240f81611f4a565b925060208401359150604084013561242681611f4a565b809150509250925092565b60005b8381101561244c578181015183820152602001612434565b50506000910152565b6000815180845261246d816020860160208601612431565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156124f4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526124e2858351612455565b945092850192908501906001016124a8565b5092979650505050505050565b6000806000806080858703121561251757600080fd5b843561252281611f4a565b9350602085013561253281611f4a565b93969395505050506040820135916060013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036125ce577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b8183526000602080850194508260005b85811015611fdb5781356125f881611f4a565b6001600160a01b0316875295820195908201906001016125e5565b6020815260006108296020830184866125d5565b6000602080838503121561263a57600080fd5b825167ffffffffffffffff81111561265157600080fd5b8301601f8101851361266257600080fd5b805161267061211482612082565b81815260069190911b8201830190838101908783111561268f57600080fd5b928401925b82841015611a8f57604084890312156126ad5760008081fd5b6126b5612028565b84516126c081611f4a565b81528486015186820152825260409093019290840190612694565b6000602082840312156126ed57600080fd5b5051919050565b60006001600160a01b03808816835286602084015280861660408401525060a0606083015261272660a0830185611f8e565b90508260808301529695505050505050565b8183526000602080850194508260005b85811015611fdb57813561275b81611f4a565b6001600160a01b03168752818301358388015260409687019690910190600101612748565b60006001600160a01b03808916835287602084015280871660408401525060a060608301526127b360a083018587612738565b9050826080830152979650505050505050565b6001600160a01b03841681526040602082015260006127e9604083018486612738565b95945050505050565b60006001600160a01b03808916835260a0602084015261281660a08401888a612738565b951660408301525060608101929092526080909101529392505050565b6000602080838503121561284657600080fd5b825167ffffffffffffffff81111561285d57600080fd5b8301601f8101851361286e57600080fd5b805161287c61211482612082565b81815260059190911b8201830190838101908783111561289b57600080fd5b928401925b82841015611a8f5783516128b381611f4a565b825292840192908401906128a0565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126128f657600080fd5b9190910192915050565b60006040823603121561291257600080fd5b61291a612028565b823561292581611f4a565b815260208381013567ffffffffffffffff81111561294257600080fd5b840136601f82011261295357600080fd5b803561296161211482612082565b81815260059190911b8201830190838101903683111561298057600080fd5b928401925b828410156129a757833561299881611f4a565b82529284019290840190612985565b938501939093525091949350505050565b60208082528181018390526000906040808401600586811b8601830188865b89811015612ad7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18c3603018112612a3857600080fd5b8b018035612a4581611f4a565b6001600160a01b0316845280880135368290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1018112612a8557600080fd5b01878101903567ffffffffffffffff811115612aa057600080fd5b80861b3603821315612ab157600080fd5b8789860152612ac388860182846125d5565b9689019694505050908601906001016129d7565b50909998505050505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612b1b57600080fd5b83018035915067ffffffffffffffff821115612b3657600080fd5b602001915036819003821315611f0157600080fd5b60006001600160a01b03808816835260a06020840152612b6e60a0840188611f8e565b9516604083015250606081019290925260809091015292915050565b600060208284031215612b9c57600080fd5b81518015158114610d0157600080fd5b600082516128f6818460208701612431565b602081526000610d01602083018461245556fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220cc266475ce423350cff3765cc33e03fce925157146b6ba892861e1309edcee9e64736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ec864be26084ba3bbf3caacf8f6961a9263319c4
-----Decoded View---------------
Arg [0] : _governor (address): 0xEC864BE26084ba3bbF3cAAcF8F6961A9263319C4
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000ec864be26084ba3bbf3caacf8f6961a9263319c4
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.