ETH Price: $2,599.56 (-1.86%)

Contract

0x24a6108D1985B44130f68550C9c43d556720CF17
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60806040169186692023-03-27 12:18:35553 days ago1679919515IN
 Create: FeeCollectorModule
0 ETH0.0312653223.20522167

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FeeCollectorModule

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
File 1 of 14 : FeeCollectorModule.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "KeeperCompatible.sol";
import "Pausable.sol";
import "IERC20.sol";

import "ISett.sol";
import "ICurvePool.sol";
import "IBalancerVault.sol";
import "IGnosisSafe.sol";

import {BaseModule} from "BaseModule.sol";
import {FeeCollectorModuleConstants} from "FeeCollectorModuleConstants.sol";

/// @title FeeCollectorModule
/// @notice Allows the module the processing of multiple sett/lp fee tokens into
///      their underlying form proportionally at a specified cadence
contract FeeCollectorModule is BaseModule, KeeperCompatibleInterface, Pausable, FeeCollectorModuleConstants {
    ////////////////////////////////////////////////////////////////////////////
    // STRUCTS & ENUM
    ////////////////////////////////////////////////////////////////////////////

    enum Protocol {
        CURVE,
        BALANCER
    }

    struct FeeInfo {
        address feeToken; // Token address of the fee processed
        bool isBadgerVault; // Boolean signaling if it is a dogfood vault or not
        Protocol protocol; // Conditional use for calling right signatures per protocol
        address curvePool; // Curve specific
        bytes32 balancerPoolId; // Balancer specific
    }

    ////////////////////////////////////////////////////////////////////////////
    // STORAGE
    ////////////////////////////////////////////////////////////////////////////

    uint256 public lastProcessingTimestamp;
    uint256 public processingInterval;

    FeeInfo[] public feeTokens;

    ////////////////////////////////////////////////////////////////////////////
    // ERRORS
    ////////////////////////////////////////////////////////////////////////////

    error NotGovernance(address caller);
    error NotKeeper(address caller);

    error TooSoon(uint256 lastProcessing, uint256 timestamp);

    error ZeroIntervalPeriod();
    error ModuleMisconfigured();

    error NotSupportedProtocol(uint8 protocol);

    ////////////////////////////////////////////////////////////////////////////
    // EVENTS
    ////////////////////////////////////////////////////////////////////////////

    event FeeTokenAdded(
        address feeToken, bool isBadgerVault, Protocol protocol, address curvePool, bytes32 balancerPoolId
    );
    event FeeSettProcessed(address feeSettToken, uint256 amount, uint256 timestamp);
    event FeeLpProcessed(address feeLpToken, uint256 amount, uint256 timestamp);

    event ProcessingIntervalUpdated(uint256 oldProcessingInterval, uint256 newProcessingInterval);

    ////////////////////////////////////////////////////////////////////////////
    // MODIFIERS
    ////////////////////////////////////////////////////////////////////////////

    /// @notice Checks whether a call is from governance
    modifier onlyGovernance() {
        if (msg.sender != GOVERNANCE) revert NotGovernance(msg.sender);
        _;
    }

    /// @notice Checks whether a call is from the keeper.
    modifier onlyKeeper() {
        if (msg.sender != CHAINLINK_KEEPER_REGISTRY) revert NotKeeper(msg.sender);
        _;
    }

    /// @param _processingInterval Frequency in seconds at which `feeToken` will be processed
    constructor(uint256 _processingInterval) {
        _setProcessingInterval(_processingInterval);
    }

    ////////////////////////////////////////////////////////////////////////////
    // PUBLIC: Governance
    ////////////////////////////////////////////////////////////////////////////

    /// @notice Adds a fee token from the Curve ecosystem to be processed
    /// @dev Fee token can be a dogfooded set, signaled with `isBadgerVault` for proper processing
    /// @param feeToken target feeToken contract address to undog and withdraw from lp
    /// @param isBadgerVault indicates if the fee token addeed is a vault or plain lp
    /// @param curvePool address of the curvePool in Curve infrastructure of the underlying token of the vault
    function addFeeTokenCurve(address feeToken, bool isBadgerVault, address curvePool) external onlyGovernance {
        feeTokens.push(
            FeeInfo({
                feeToken: feeToken,
                isBadgerVault: isBadgerVault,
                protocol: Protocol.CURVE,
                curvePool: curvePool,
                balancerPoolId: bytes32(0)
            })
        );

        emit FeeTokenAdded(feeToken, isBadgerVault, Protocol.CURVE, curvePool, bytes32(0));
    }

    /// @notice Adds a fee token from the Balancer ecosystem to be processed
    /// @dev Fee token can be a dogfooded set, signaled with `isBadgerVault` for proper processing
    /// @param feeToken target feeToken contract address to undog and withdraw from lp
    /// @param isBadgerVault indicates if the fee token addeed is a vault or plain lp
    /// @param balancerPoolId bytes id of the Balancer curvePool for the underlying of the token of the vault
    function addFeeTokenBalancer(address feeToken, bool isBadgerVault, bytes32 balancerPoolId)
        external
        onlyGovernance
    {
        feeTokens.push(
            FeeInfo({
                feeToken: feeToken,
                isBadgerVault: isBadgerVault,
                protocol: Protocol.BALANCER,
                curvePool: address(0),
                balancerPoolId: balancerPoolId
            })
        );
        emit FeeTokenAdded(feeToken, isBadgerVault, Protocol.BALANCER, address(0), balancerPoolId);
    }

    /// @notice Updates the interval at which the fees are processed. Can only be called by governance.
    /// @param _processingInterval The new frequency period in seconds for processing `feeToken` in storage.
    function setProcessingInterval(uint256 _processingInterval) external onlyGovernance {
        _setProcessingInterval(_processingInterval);
    }

    /// @dev Pauses the contract, which prevents executing performUpkeep.
    function pause() external onlyGovernance {
        _pause();
    }

    /// @dev Unpauses the contract.
    function unpause() external onlyGovernance {
        _unpause();
    }

    ////////////////////////////////////////////////////////////////////////////
    // PUBLIC: Keeper
    ////////////////////////////////////////////////////////////////////////////

    /// @dev Contains the logic that should be executed on-chain when
    ///      `checkUpkeep` returns true.
    function performUpkeep(bytes calldata performData) external override whenNotPaused onlyKeeper {
        /// @dev safety check, ensuring onchain module is enabled in the gnosis safe
        if (!SAFE.isModuleEnabled(address(this))) revert ModuleMisconfigured();

        // NOTE: only we enforce cadence condition in the check-up for simplicity
        //       rather than evaluating each other `feeToken` pricing
        if ((block.timestamp - lastProcessingTimestamp) < processingInterval) {
            revert TooSoon(lastProcessingTimestamp, block.timestamp);
        }

        uint256 feeTokensLen = feeTokens.length;
        if (feeTokensLen > 0) {
            for (uint256 i; i < feeTokensLen;) {
                FeeInfo memory info = feeTokens[i];
                if (info.isBadgerVault) {
                    // 1. Undogs from the vault `feeToken`
                    address lpToken = _withdrawSett(info.feeToken);
                    // 2. Withdraw proportionally into the lp underlyings
                    if (lpToken != address(0)) {
                        _withdrawLpToken(lpToken, info);
                    }
                } else {
                    // NOTE: here is assumed right gov configuration, and `feeToken` is indeed a lp fee
                    _withdrawLpToken(info.feeToken, info);
                }
                // TODO: Process them based on TCDs-Cowswap on-chain orders. Next iteration after 1st version trial
                unchecked {
                    ++i;
                }
            }
            lastProcessingTimestamp = block.timestamp;
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    // INTERNAL
    ////////////////////////////////////////////////////////////////////////////

    /// @notice Updates the interval at which the fees are processed. Can only be called by governance.
    /// @param _processingInterval The new frequency period in seconds for processing `feeToken` in storage.
    function _setProcessingInterval(uint256 _processingInterval) internal {
        if (_processingInterval == 0) revert ZeroIntervalPeriod();

        uint256 oldProcessingInterval = processingInterval;

        processingInterval = _processingInterval;
        emit ProcessingIntervalUpdated(oldProcessingInterval, _processingInterval);
    }

    /// @notice Allows to undog-food from a sett
    /// @param feeToken Contract address to withdraw from
    /// @return address Contract address of the underlying token that was withdrawn
    function _withdrawSett(address feeToken) internal returns (address) {
        ISett sett = ISett(feeToken);
        uint256 feeShares = sett.balanceOf(address(SAFE));
        if (feeShares > 0) {
            _checkTransactionAndExecute(SAFE, feeToken, abi.encodeCall(ISett.withdraw, feeShares));
            emit FeeSettProcessed(feeToken, feeShares, block.timestamp);
            return sett.token();
        }
        return address(0);
    }

    /// @notice Allows to withdraw a LP proportionally to its underlyings
    /// @param lpToken Contract address to withdraw proportionally into underlyings from
    /// @param info Contains details defined in the struct `FeeInfo`
    function _withdrawLpToken(address lpToken, FeeInfo memory info) internal {
        uint256 burnAmount = IERC20(lpToken).balanceOf(address(SAFE));
        if (burnAmount > 0) {
            if (info.protocol == Protocol.CURVE) {
                uint256[2] memory minAmounts;
                _checkTransactionAndExecute(
                    SAFE, info.curvePool, abi.encodeCall(ICurvePool.remove_liquidity, (burnAmount, minAmounts))
                );
            } else if (info.protocol == Protocol.BALANCER) {
                (address[] memory tokens,,) = BALANCER_VAULT.getPoolTokens(info.balancerPoolId);
                IBalancerVault.ExitPoolRequest memory request = IBalancerVault.ExitPoolRequest({
                    assets: tokens,
                    minAmountsOut: new uint256[](tokens.length),
                    userData: abi.encode(EXACT_BPT_IN_FOR_TOKENS_OUT, burnAmount),
                    toInternalBalance: false
                });
                _checkTransactionAndExecute(
                    SAFE,
                    address(BALANCER_VAULT),
                    abi.encodeCall(
                        IBalancerVault.exitPool, (info.balancerPoolId, address(SAFE), address(SAFE), request)
                    )
                );
            } else {
                revert NotSupportedProtocol(uint8(info.protocol));
            }
            emit FeeLpProcessed(lpToken, burnAmount, block.timestamp);
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    // PUBLIC VIEW
    ////////////////////////////////////////////////////////////////////////////

    /// @notice Checks whether an upkeep is to be performed.
    /// @return upkeepNeeded_ A boolean indicating whether an upkeep is to be performed.
    /// @return performData_ The calldata to be passed to the upkeep function.
    function checkUpkeep(bytes calldata)
        external
        view
        override
        returns (bool upkeepNeeded_, bytes memory performData_)
    {
        if (
            (block.timestamp - lastProcessingTimestamp) > processingInterval && feeTokens.length > 0
                && SAFE.isModuleEnabled(address(this))
        ) {
            upkeepNeeded_ = true;
        }
    }

    /// @notice Returns the length of `feeTokens` being processed
    function feeTokensLength() external view returns (uint256) {
        return feeTokens.length;
    }
}

File 2 of 14 : KeeperCompatible.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "KeeperBase.sol";
import "KeeperCompatibleInterface.sol";

abstract contract KeeperCompatible is KeeperBase, KeeperCompatibleInterface {}

File 3 of 14 : KeeperBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract KeeperBase {
  error OnlySimulatedBackend();

  /**
   * @notice method that allows it to be simulated via eth_call by checking that
   * the sender is the zero address.
   */
  function preventExecution() internal view {
    if (tx.origin != address(0)) {
      revert OnlySimulatedBackend();
    }
  }

  /**
   * @notice modifier that allows it to be simulated via eth_call by checking
   * that the sender is the zero address.
   */
  modifier cannotExecute() {
    preventExecution();
    _;
  }
}

File 4 of 14 : KeeperCompatibleInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface KeeperCompatibleInterface {
  /**
   * @notice method that is simulated by the keepers to see if any work actually
   * needs to be performed. This method does does not actually need to be
   * executable, and since it is only ever simulated it can consume lots of gas.
   * @dev To ensure that it is never called, you may want to add the
   * cannotExecute modifier from KeeperBase to your implementation of this
   * method.
   * @param checkData specified in the upkeep registration so it is always the
   * same for a registered upkeep. This can easily be broken down into specific
   * arguments using `abi.decode`, so multiple upkeeps can be registered on the
   * same contract and easily differentiated by the contract.
   * @return upkeepNeeded boolean to indicate whether the keeper should call
   * performUpkeep or not.
   * @return performData bytes that the keeper should call performUpkeep with, if
   * upkeep is needed. If you would like to encode data to decode later, try
   * `abi.encode`.
   */
  function checkUpkeep(bytes calldata checkData) external returns (bool upkeepNeeded, bytes memory performData);

  /**
   * @notice method that is actually executed by the keepers, via the registry.
   * The data returned by the checkUpkeep simulation will be passed into
   * this method to actually be executed.
   * @dev The input to this method should not be trusted, and the caller of the
   * method should not even be restricted to any single registry. Anyone should
   * be able call it, and the input should be validated, there is no guarantee
   * that the data passed in is the performData returned from checkUpkeep. This
   * could happen due to malicious keepers, racing keepers, or simply a state
   * change while the performUpkeep transaction is waiting for confirmation.
   * Always validate the data passed in.
   * @param performData is the data which was passed back from the checkData
   * simulation. If it is encoded, it can easily be decoded into other types by
   * calling `abi.decode`. This data should not be trusted, and should be
   * validated against the contract's current state.
   */
  function performUpkeep(bytes calldata performData) external;
}

File 5 of 14 : Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;

import "Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

File 6 of 14 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 7 of 14 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `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);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 8 of 14 : ISett.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

interface ISett {
    function balanceOf(address account) external view returns (uint256);
    
    function token() external view returns (address);

    function withdraw(uint256 _shares) external;

    function withdrawAll() external;
}

File 9 of 14 : ICurvePool.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ICurvePool {
    // Exchange using WETH by default
    function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external returns (uint256);

    function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy, address receiver)
        external
        returns (uint256);

    function remove_liquidity(uint256 _amount, uint256[2] calldata _amounts) external;
}

File 10 of 14 : IBalancerVault.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.4;

interface IBalancerVault {
    struct ExitPoolRequest {
        address[] assets;
        uint256[] minAmountsOut;
        bytes userData;
        bool toInternalBalance; 
    }

   function exitPool(
        bytes32 poolId,
        address sender,
        address recipient,
        ExitPoolRequest memory request
    ) external;

    function getPoolTokens(bytes32 poolId)
        external
        view
        returns (
            address[] memory tokens,
            uint256[] memory balances,
            uint256 lastChangeBlock
        );

}

File 11 of 14 : IGnosisSafe.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

interface IGnosisSafe {
    event DisabledModule(address module);
    event EnabledModule(address module);

    enum Operation {
        Call,
        DelegateCall
    }

    /// @dev Allows a Module to execute a Safe transaction without any further confirmations.
    /// @param to Destination address of module transaction.
    /// @param value Ether value of module transaction.
    /// @param data Data payload of module transaction.
    /// @param operation Operation type of module transaction.
    function execTransactionFromModule(
        address to,
        uint256 value,
        bytes calldata data,
        Operation operation
    ) external returns (bool success);

    /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data
    /// @param to Destination address of module transaction.
    /// @param value Ether value of module transaction.
    /// @param data Data payload of module transaction.
    /// @param operation Operation type of module transaction.
    function execTransactionFromModuleReturnData(address to, uint256 value, bytes calldata data, Operation operation)
        external
        returns (bool success, bytes memory returnData);

    function enableModule(address module) external;
    
    function disableModule(address prevModule, address module) external;

    function getModules() external view returns (address[] memory);

    function isModuleEnabled(address module) external view returns (bool);
}

File 12 of 14 : BaseModule.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "IGnosisSafe.sol";

contract BaseModule {
    ////////////////////////////////////////////////////////////////////////////
    // ERRORS
    ////////////////////////////////////////////////////////////////////////////

    error ExecutionFailure(address to, bytes data, uint256 timestamp);

    ////////////////////////////////////////////////////////////////////////////
    // INTERNAL
    ////////////////////////////////////////////////////////////////////////////

    /// @notice Allows executing specific calldata into an address thru a gnosis-safe, which have enable this contract as module.
    /// @param to Contract address where we will execute the calldata.
    /// @param data Calldata to be executed within the boundaries of the `allowedFunctions`.
    function _checkTransactionAndExecute(IGnosisSafe safe, address to, bytes memory data) internal {
        if (data.length >= 4) {
            bool success = safe.execTransactionFromModule(to, 0, data, IGnosisSafe.Operation.Call);
            if (!success) revert ExecutionFailure(to, data, block.timestamp);
        }
    }

    /// @notice Allows executing specific calldata into an address thru a gnosis-safe, which have enable this contract as module.
    /// @param to Contract address where we will execute the calldata.
    /// @param data Calldata to be executed within the boundaries of the `allowedFunctions`.
    /// @return bytes data containing the return data from the method in `to` with the payload `data`
    function _checkTransactionAndExecuteReturningData(IGnosisSafe safe, address to, bytes memory data)
        internal
        returns (bytes memory)
    {
        if (data.length >= 4) {
            (bool success, bytes memory returnData) =
                safe.execTransactionFromModuleReturnData(to, 0, data, IGnosisSafe.Operation.Call);
            if (!success) revert ExecutionFailure(to, data, block.timestamp);
            return returnData;
        }
    }
}

File 13 of 14 : FeeCollectorModuleConstants.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "IMetaRegistry.sol";
import "IBalancerVault.sol";
import "IGnosisSafe.sol";

abstract contract FeeCollectorModuleConstants {
    address public constant GOVERNANCE = 0x042B32Ac6b453485e357938bdC38e0340d4b9276;
    IGnosisSafe public constant SAFE = IGnosisSafe(GOVERNANCE);

    // Chainlink
    address constant CHAINLINK_KEEPER_REGISTRY = 0x02777053d6764996e594c3E88AF1D58D5363a2e6;

    // Curve
    IMetaRegistry META_REGISTRY = IMetaRegistry(0xF98B45FA17DE75FB1aD0e7aFD971b0ca00e379fC);

    // Balancer
    IBalancerVault BALANCER_VAULT = IBalancerVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8);
    uint256 constant EXACT_BPT_IN_FOR_TOKENS_OUT = 1;
}

File 14 of 14 : IMetaRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

interface IMetaRegistry {
    function get_n_coins(address) external view returns (uint256);

    function get_pool_asset_type(address) external view returns  (uint256);

    function get_pool_name(address) external view returns  (string calldata);
}

Settings
{
  "evmVersion": "istanbul",
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "libraries": {
    "FeeCollectorModule.sol": {}
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_processingInterval","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"ExecutionFailure","type":"error"},{"inputs":[],"name":"ModuleMisconfigured","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NotGovernance","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NotKeeper","type":"error"},{"inputs":[{"internalType":"uint8","name":"protocol","type":"uint8"}],"name":"NotSupportedProtocol","type":"error"},{"inputs":[{"internalType":"uint256","name":"lastProcessing","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TooSoon","type":"error"},{"inputs":[],"name":"ZeroIntervalPeriod","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"feeLpToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"FeeLpProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"feeSettToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"FeeSettProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"feeToken","type":"address"},{"indexed":false,"internalType":"bool","name":"isBadgerVault","type":"bool"},{"indexed":false,"internalType":"enum FeeCollectorModule.Protocol","name":"protocol","type":"uint8"},{"indexed":false,"internalType":"address","name":"curvePool","type":"address"},{"indexed":false,"internalType":"bytes32","name":"balancerPoolId","type":"bytes32"}],"name":"FeeTokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldProcessingInterval","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newProcessingInterval","type":"uint256"}],"name":"ProcessingIntervalUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"GOVERNANCE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SAFE","outputs":[{"internalType":"contract IGnosisSafe","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"bool","name":"isBadgerVault","type":"bool"},{"internalType":"bytes32","name":"balancerPoolId","type":"bytes32"}],"name":"addFeeTokenBalancer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"bool","name":"isBadgerVault","type":"bool"},{"internalType":"address","name":"curvePool","type":"address"}],"name":"addFeeTokenCurve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded_","type":"bool"},{"internalType":"bytes","name":"performData_","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"feeTokens","outputs":[{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"bool","name":"isBadgerVault","type":"bool"},{"internalType":"enum FeeCollectorModule.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"curvePool","type":"address"},{"internalType":"bytes32","name":"balancerPoolId","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeTokensLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastProcessingTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"performUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"processingInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_processingInterval","type":"uint256"}],"name":"setProcessingInterval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000805474f98b45fa17de75fb1ad0e7afd971b0ca00e379fc00610100600160a81b0319909116179055600180546001600160a01b03191673ba12222222228d8ba445958a75a0704d566bf2c817905534801561006057600080fd5b5060405161174038038061174083398101604081905261007f916100fe565b6000805460ff1916905561009281610098565b50610117565b806000036100b95760405163a0d5b9b360e01b815260040160405180910390fd5b600380549082905560408051828152602081018490527f6cc9b6735fc4f6325f72af2d92aa67bf73a68b7641bb08fa71cb48068df7c6d5910160405180910390a15050565b60006020828403121561011057600080fd5b5051919050565b61161a806101266000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636e04ff0d1161008c5780638ef4403c116100665780638ef4403c146101ba578063abbdf9e8146101de578063d401427d146101e7578063f3074b93146101fa57600080fd5b80636e04ff0d146101915780638456cb59146101b2578063885a1ffa1461011757600080fd5b80633c590e76116100c85780633c590e76146101495780633f4ba83a146101605780634585e33b146101685780635c975abb1461017b57600080fd5b8063085b3af6146100ef5780630d7eb587146101045780631462783414610117575b600080fd5b6101026100fd366004610ff4565b610202565b005b610102610112366004611035565b610370565b61012c6000805160206115c583398151915281565b6040516001600160a01b0390911681526020015b60405180910390f35b61015260035481565b604051908152602001610140565b6101026103ac565b61010261017636600461104e565b6103e6565b60005460ff166040519015158152602001610140565b6101a461019f36600461104e565b610642565b604051610140929190611106565b6101026106ea565b6101cd6101c8366004611035565b610722565b604051610140959493929190611155565b61015260025481565b6101026101f5366004611197565b610777565b600454610152565b336000805160206115c5833981519152146102375760405163988d1f0360e01b81523360048201526024015b60405180910390fd5b6040805160a0810182526001600160a01b03858116825284151560208301908152600193830184815260006060850181905260808501879052600480548088018255915284517f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b600390920291909101805493511515600160a01b026001600160a81b031990941691909416179190911780835590519293919291839160ff60a81b191690600160a81b9084908111156102f3576102f3611121565b02179055506060820151600182810180546001600160a01b0319166001600160a01b03909316929092179091556080909201516002909101556040517f1a875109dbd029d90e7a177ace8df845812b3b93243d1a6ab9c668d7077f05989161036391869186916000908790611155565b60405180910390a1505050565b336000805160206115c5833981519152146103a05760405163988d1f0360e01b815233600482015260240161022e565b6103a9816108c3565b50565b336000805160206115c5833981519152146103dc5760405163988d1f0360e01b815233600482015260240161022e565b6103e4610929565b565b60005460ff161561042c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161022e565b337302777053d6764996e594c3e88af1d58d5363a2e6146104625760405163ccf79b6760e01b815233600482015260240161022e565b604051632d9ad53d60e01b81523060048201526000805160206115c583398151915290632d9ad53d90602401602060405180830381865afa1580156104ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104cf91906111e2565b6104ec576040516393f2af9f60e01b815260040160405180910390fd5b6003546002546104fc9042611206565b1015610528576002546040516358dcdb7760e11b8152600481019190915242602482015260440161022e565b600454801561063d5760005b81811015610637576000600482815481106105515761055161122d565b60009182526020918290206040805160a081018252600390930290910180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b90041660018111156105b1576105b1611121565b60018111156105c2576105c2611121565b815260018201546001600160a01b03166020808301919091526002909201546040909101528101519091501561062257600061060182600001516109bc565b90506001600160a01b0381161561061c5761061c8183610b52565b5061062e565b805161062e9082610b52565b50600101610534565b50426002555b505050565b60006060600354600254426106579190611206565b118015610665575060045415155b80156106d95750604051632d9ad53d60e01b81523060048201526000805160206115c583398151915290632d9ad53d90602401602060405180830381865afa1580156106b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d991906111e2565b156106e357600191505b9250929050565b336000805160206115c58339815191521461071a5760405163988d1f0360e01b815233600482015260240161022e565b6103e4610e8b565b6004818154811061073257600080fd5b60009182526020909120600390910201805460018201546002909201546001600160a01b03808316945060ff600160a01b8404811694600160a81b9094041692169085565b336000805160206115c5833981519152146107a75760405163988d1f0360e01b815233600482015260240161022e565b6040805160a0810182526001600160a01b038516815283151560208201526004918101600081526001600160a01b03808516602080840191909152600060409384018190528554600181810188559682529082902085516003909202018054928601511515600160a01b026001600160a81b0319909316919093161717808255918301519293909291839160ff60a81b1990911690600160a81b90849081111561085357610853611121565b021790555060608201516001820180546001600160a01b0319166001600160a01b039092169190911790556080909101516002909101556040517f1a875109dbd029d90e7a177ace8df845812b3b93243d1a6ab9c668d7077f059890610363908590859060009086908290611155565b806000036108e45760405163a0d5b9b360e01b815260040160405180910390fd5b600380549082905560408051828152602081018490527f6cc9b6735fc4f6325f72af2d92aa67bf73a68b7641bb08fa71cb48068df7c6d5910160405180910390a15050565b60005460ff166109725760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161022e565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6040516370a0823160e01b81526000805160206115c58339815191526004820152600090829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a399190611243565b90508015610b4857610a966000805160206115c58339815191528583604051602401610a6791815260200190565b60408051601f198184030181529190526020810180516001600160e01b0316632e1a7d4d60e01b179052610f06565b604080516001600160a01b038616815260208101839052428183015290517f406f62993af09e9751e0551e223926ab8aa8da79ec56d2ff663e21c25071b0de9181900360600190a1816001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b40919061125c565b949350505050565b5060009392505050565b6040516370a0823160e01b81526000805160206115c583398151915260048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610ba7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcb9190611243565b9050801561063d57600082604001516001811115610beb57610beb611121565b03610c5757610bf8610fb3565b610c516000805160206115c583398151915284606001518484604051602401610c22929190611279565b60408051601f198184030181529190526020810180516001600160e01b03166316cd8e2760e21b179052610f06565b50610e42565b600182604001516001811115610c6f57610c6f611121565b03610e0d576001546080830151604051631f29a8cd60e31b815260048101919091526000916001600160a01b03169063f94d466890602401600060405180830381865afa158015610cc4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cec9190810190611387565b5050905060006040518060800160405280838152602001835167ffffffffffffffff811115610d1d57610d1d6112b1565b604051908082528060200260200182016040528015610d46578160200160208202803683370190505b508152602001600185604051602001610d69929190918252602082015260400190565b6040516020818303038152906040528152602001600015158152509050610e066000805160206115c5833981519152600160009054906101000a90046001600160a01b031686608001516000805160206115c58339815191528086604051602401610dd79493929190611490565b60408051601f198184030181529190526020810180516001600160e01b0316638bdb391360e01b179052610f06565b5050610e42565b81604001516001811115610e2357610e23611121565b604051634ec2d39760e01b815260ff909116600482015260240161022e565b604080516001600160a01b03851681526020810183905242918101919091527fa6712e266fd2cc3f1352db481bf56939fe1924bed08005f5ac4d9ad2242d211d90606001610363565b60005460ff1615610ed15760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161022e565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861099f3390565b600481511061063d5760405163468721a760e01b81526000906001600160a01b0385169063468721a790610f4490869085908790829060040161154f565b6020604051808303816000875af1158015610f63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8791906111e2565b905080610fad578282426040516321db15cf60e11b815260040161022e93929190611590565b50505050565b60405180604001604052806002906020820280368337509192915050565b6001600160a01b03811681146103a957600080fd5b80151581146103a957600080fd5b60008060006060848603121561100957600080fd5b833561101481610fd1565b9250602084013561102481610fe6565b929592945050506040919091013590565b60006020828403121561104757600080fd5b5035919050565b6000806020838503121561106157600080fd5b823567ffffffffffffffff8082111561107957600080fd5b818501915085601f83011261108d57600080fd5b81358181111561109c57600080fd5b8660208285010111156110ae57600080fd5b60209290920196919550909350505050565b6000815180845260005b818110156110e6576020818501810151868301820152016110ca565b506000602082860101526020601f19601f83011685010191505092915050565b8215158152604060208201526000610b4060408301846110c0565b634e487b7160e01b600052602160045260246000fd5b600281106103a957634e487b7160e01b600052602160045260246000fd5b6001600160a01b038681168252851515602083015260a082019061117886611137565b8560408401528085166060840152508260808301529695505050505050565b6000806000606084860312156111ac57600080fd5b83356111b781610fd1565b925060208401356111c781610fe6565b915060408401356111d781610fd1565b809150509250925092565b6000602082840312156111f457600080fd5b81516111ff81610fe6565b9392505050565b8181038181111561122757634e487b7160e01b600052601160045260246000fd5b92915050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561125557600080fd5b5051919050565b60006020828403121561126e57600080fd5b81516111ff81610fd1565b8281526060810160208083018460005b60028110156112a657815183529183019190830190600101611289565b505050509392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156112f0576112f06112b1565b604052919050565b600067ffffffffffffffff821115611312576113126112b1565b5060051b60200190565b600082601f83011261132d57600080fd5b8151602061134261133d836112f8565b6112c7565b82815260059290921b8401810191818101908684111561136157600080fd5b8286015b8481101561137c5780518352918301918301611365565b509695505050505050565b60008060006060848603121561139c57600080fd5b835167ffffffffffffffff808211156113b457600080fd5b818601915086601f8301126113c857600080fd5b815160206113d861133d836112f8565b82815260059290921b8401810191818101908a8411156113f757600080fd5b948201945b8386101561141e57855161140f81610fd1565b825294820194908201906113fc565b9189015191975090935050508082111561143757600080fd5b506114448682870161131c565b925050604084015190509250925092565b600081518084526020808501945080840160005b8381101561148557815187529582019590820190600101611469565b509495945050505050565b8481526000602060018060a01b038087168285015280861660408501526080606085015261010084018551608080870152818151808452610120880191508583019350600092505b808310156114fa578351851682529285019260019290920191908501906114d8565b50848801519450607f199350838782030160a088015261151a8186611455565b94505050506040850151818584030160c086015261153883826110c0565b92505050606084015161137c60e085018215159052565b60018060a01b038516815283602082015260806040820152600061157660808301856110c0565b905061158183611137565b82606083015295945050505050565b6001600160a01b03841681526060602082018190526000906115b4908301856110c0565b905082604083015294935050505056fe000000000000000000000000042b32ac6b453485e357938bdc38e0340d4b9276a2646970667358221220a0dfe36324da0335b1fa0b5f3058c914ccd42296d61475953fca9f2186d9cbda64736f6c634300081100330000000000000000000000000000000000000000000000000000000000282170

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636e04ff0d1161008c5780638ef4403c116100665780638ef4403c146101ba578063abbdf9e8146101de578063d401427d146101e7578063f3074b93146101fa57600080fd5b80636e04ff0d146101915780638456cb59146101b2578063885a1ffa1461011757600080fd5b80633c590e76116100c85780633c590e76146101495780633f4ba83a146101605780634585e33b146101685780635c975abb1461017b57600080fd5b8063085b3af6146100ef5780630d7eb587146101045780631462783414610117575b600080fd5b6101026100fd366004610ff4565b610202565b005b610102610112366004611035565b610370565b61012c6000805160206115c583398151915281565b6040516001600160a01b0390911681526020015b60405180910390f35b61015260035481565b604051908152602001610140565b6101026103ac565b61010261017636600461104e565b6103e6565b60005460ff166040519015158152602001610140565b6101a461019f36600461104e565b610642565b604051610140929190611106565b6101026106ea565b6101cd6101c8366004611035565b610722565b604051610140959493929190611155565b61015260025481565b6101026101f5366004611197565b610777565b600454610152565b336000805160206115c5833981519152146102375760405163988d1f0360e01b81523360048201526024015b60405180910390fd5b6040805160a0810182526001600160a01b03858116825284151560208301908152600193830184815260006060850181905260808501879052600480548088018255915284517f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b600390920291909101805493511515600160a01b026001600160a81b031990941691909416179190911780835590519293919291839160ff60a81b191690600160a81b9084908111156102f3576102f3611121565b02179055506060820151600182810180546001600160a01b0319166001600160a01b03909316929092179091556080909201516002909101556040517f1a875109dbd029d90e7a177ace8df845812b3b93243d1a6ab9c668d7077f05989161036391869186916000908790611155565b60405180910390a1505050565b336000805160206115c5833981519152146103a05760405163988d1f0360e01b815233600482015260240161022e565b6103a9816108c3565b50565b336000805160206115c5833981519152146103dc5760405163988d1f0360e01b815233600482015260240161022e565b6103e4610929565b565b60005460ff161561042c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161022e565b337302777053d6764996e594c3e88af1d58d5363a2e6146104625760405163ccf79b6760e01b815233600482015260240161022e565b604051632d9ad53d60e01b81523060048201526000805160206115c583398151915290632d9ad53d90602401602060405180830381865afa1580156104ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104cf91906111e2565b6104ec576040516393f2af9f60e01b815260040160405180910390fd5b6003546002546104fc9042611206565b1015610528576002546040516358dcdb7760e11b8152600481019190915242602482015260440161022e565b600454801561063d5760005b81811015610637576000600482815481106105515761055161122d565b60009182526020918290206040805160a081018252600390930290910180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b90041660018111156105b1576105b1611121565b60018111156105c2576105c2611121565b815260018201546001600160a01b03166020808301919091526002909201546040909101528101519091501561062257600061060182600001516109bc565b90506001600160a01b0381161561061c5761061c8183610b52565b5061062e565b805161062e9082610b52565b50600101610534565b50426002555b505050565b60006060600354600254426106579190611206565b118015610665575060045415155b80156106d95750604051632d9ad53d60e01b81523060048201526000805160206115c583398151915290632d9ad53d90602401602060405180830381865afa1580156106b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d991906111e2565b156106e357600191505b9250929050565b336000805160206115c58339815191521461071a5760405163988d1f0360e01b815233600482015260240161022e565b6103e4610e8b565b6004818154811061073257600080fd5b60009182526020909120600390910201805460018201546002909201546001600160a01b03808316945060ff600160a01b8404811694600160a81b9094041692169085565b336000805160206115c5833981519152146107a75760405163988d1f0360e01b815233600482015260240161022e565b6040805160a0810182526001600160a01b038516815283151560208201526004918101600081526001600160a01b03808516602080840191909152600060409384018190528554600181810188559682529082902085516003909202018054928601511515600160a01b026001600160a81b0319909316919093161717808255918301519293909291839160ff60a81b1990911690600160a81b90849081111561085357610853611121565b021790555060608201516001820180546001600160a01b0319166001600160a01b039092169190911790556080909101516002909101556040517f1a875109dbd029d90e7a177ace8df845812b3b93243d1a6ab9c668d7077f059890610363908590859060009086908290611155565b806000036108e45760405163a0d5b9b360e01b815260040160405180910390fd5b600380549082905560408051828152602081018490527f6cc9b6735fc4f6325f72af2d92aa67bf73a68b7641bb08fa71cb48068df7c6d5910160405180910390a15050565b60005460ff166109725760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161022e565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6040516370a0823160e01b81526000805160206115c58339815191526004820152600090829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015610a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a399190611243565b90508015610b4857610a966000805160206115c58339815191528583604051602401610a6791815260200190565b60408051601f198184030181529190526020810180516001600160e01b0316632e1a7d4d60e01b179052610f06565b604080516001600160a01b038616815260208101839052428183015290517f406f62993af09e9751e0551e223926ab8aa8da79ec56d2ff663e21c25071b0de9181900360600190a1816001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b40919061125c565b949350505050565b5060009392505050565b6040516370a0823160e01b81526000805160206115c583398151915260048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610ba7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcb9190611243565b9050801561063d57600082604001516001811115610beb57610beb611121565b03610c5757610bf8610fb3565b610c516000805160206115c583398151915284606001518484604051602401610c22929190611279565b60408051601f198184030181529190526020810180516001600160e01b03166316cd8e2760e21b179052610f06565b50610e42565b600182604001516001811115610c6f57610c6f611121565b03610e0d576001546080830151604051631f29a8cd60e31b815260048101919091526000916001600160a01b03169063f94d466890602401600060405180830381865afa158015610cc4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cec9190810190611387565b5050905060006040518060800160405280838152602001835167ffffffffffffffff811115610d1d57610d1d6112b1565b604051908082528060200260200182016040528015610d46578160200160208202803683370190505b508152602001600185604051602001610d69929190918252602082015260400190565b6040516020818303038152906040528152602001600015158152509050610e066000805160206115c5833981519152600160009054906101000a90046001600160a01b031686608001516000805160206115c58339815191528086604051602401610dd79493929190611490565b60408051601f198184030181529190526020810180516001600160e01b0316638bdb391360e01b179052610f06565b5050610e42565b81604001516001811115610e2357610e23611121565b604051634ec2d39760e01b815260ff909116600482015260240161022e565b604080516001600160a01b03851681526020810183905242918101919091527fa6712e266fd2cc3f1352db481bf56939fe1924bed08005f5ac4d9ad2242d211d90606001610363565b60005460ff1615610ed15760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161022e565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861099f3390565b600481511061063d5760405163468721a760e01b81526000906001600160a01b0385169063468721a790610f4490869085908790829060040161154f565b6020604051808303816000875af1158015610f63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8791906111e2565b905080610fad578282426040516321db15cf60e11b815260040161022e93929190611590565b50505050565b60405180604001604052806002906020820280368337509192915050565b6001600160a01b03811681146103a957600080fd5b80151581146103a957600080fd5b60008060006060848603121561100957600080fd5b833561101481610fd1565b9250602084013561102481610fe6565b929592945050506040919091013590565b60006020828403121561104757600080fd5b5035919050565b6000806020838503121561106157600080fd5b823567ffffffffffffffff8082111561107957600080fd5b818501915085601f83011261108d57600080fd5b81358181111561109c57600080fd5b8660208285010111156110ae57600080fd5b60209290920196919550909350505050565b6000815180845260005b818110156110e6576020818501810151868301820152016110ca565b506000602082860101526020601f19601f83011685010191505092915050565b8215158152604060208201526000610b4060408301846110c0565b634e487b7160e01b600052602160045260246000fd5b600281106103a957634e487b7160e01b600052602160045260246000fd5b6001600160a01b038681168252851515602083015260a082019061117886611137565b8560408401528085166060840152508260808301529695505050505050565b6000806000606084860312156111ac57600080fd5b83356111b781610fd1565b925060208401356111c781610fe6565b915060408401356111d781610fd1565b809150509250925092565b6000602082840312156111f457600080fd5b81516111ff81610fe6565b9392505050565b8181038181111561122757634e487b7160e01b600052601160045260246000fd5b92915050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561125557600080fd5b5051919050565b60006020828403121561126e57600080fd5b81516111ff81610fd1565b8281526060810160208083018460005b60028110156112a657815183529183019190830190600101611289565b505050509392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156112f0576112f06112b1565b604052919050565b600067ffffffffffffffff821115611312576113126112b1565b5060051b60200190565b600082601f83011261132d57600080fd5b8151602061134261133d836112f8565b6112c7565b82815260059290921b8401810191818101908684111561136157600080fd5b8286015b8481101561137c5780518352918301918301611365565b509695505050505050565b60008060006060848603121561139c57600080fd5b835167ffffffffffffffff808211156113b457600080fd5b818601915086601f8301126113c857600080fd5b815160206113d861133d836112f8565b82815260059290921b8401810191818101908a8411156113f757600080fd5b948201945b8386101561141e57855161140f81610fd1565b825294820194908201906113fc565b9189015191975090935050508082111561143757600080fd5b506114448682870161131c565b925050604084015190509250925092565b600081518084526020808501945080840160005b8381101561148557815187529582019590820190600101611469565b509495945050505050565b8481526000602060018060a01b038087168285015280861660408501526080606085015261010084018551608080870152818151808452610120880191508583019350600092505b808310156114fa578351851682529285019260019290920191908501906114d8565b50848801519450607f199350838782030160a088015261151a8186611455565b94505050506040850151818584030160c086015261153883826110c0565b92505050606084015161137c60e085018215159052565b60018060a01b038516815283602082015260806040820152600061157660808301856110c0565b905061158183611137565b82606083015295945050505050565b6001600160a01b03841681526060602082018190526000906115b4908301856110c0565b905082604083015294935050505056fe000000000000000000000000042b32ac6b453485e357938bdc38e0340d4b9276a2646970667358221220a0dfe36324da0335b1fa0b5f3058c914ccd42296d61475953fca9f2186d9cbda64736f6c63430008110033

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

0000000000000000000000000000000000000000000000000000000000282170

-----Decoded View---------------
Arg [0] : _processingInterval (uint256): 2630000

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000282170


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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.