Goerli Testnet

Contract

0x8180949ac41EF18e844ff8dafE604a195d86Aea9

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Value
0x6101006055742912021-09-27 23:40:22913 days ago1632786022IN
 Create: TopUpRewardPrograms
0 ETH0.001630092.2816825

Latest 25 internal transactions (View All)

Advanced mode:
Parent Txn Hash Block From To Value
81211262022-12-12 8:42:48473 days ago1670834568
0x8180949a...95d86Aea9
0 ETH
81211262022-12-12 8:42:48473 days ago1670834568
0x8180949a...95d86Aea9
0 ETH
81176792022-12-11 18:53:36473 days ago1670784816
0x8180949a...95d86Aea9
0 ETH
81176792022-12-11 18:53:36473 days ago1670784816
0x8180949a...95d86Aea9
0 ETH
80015952022-11-22 22:53:24492 days ago1669157604
0x8180949a...95d86Aea9
0 ETH
80015952022-11-22 22:53:24492 days ago1669157604
0x8180949a...95d86Aea9
0 ETH
79995852022-11-22 14:51:48493 days ago1669128708
0x8180949a...95d86Aea9
0 ETH
79995852022-11-22 14:51:48493 days ago1669128708
0x8180949a...95d86Aea9
0 ETH
69049232022-05-18 7:33:03681 days ago1652859183
0x8180949a...95d86Aea9
0 ETH
69049232022-05-18 7:33:03681 days ago1652859183
0x8180949a...95d86Aea9
0 ETH
69049232022-05-18 7:33:03681 days ago1652859183
0x8180949a...95d86Aea9
0 ETH
69016032022-05-17 17:42:34681 days ago1652809354
0x8180949a...95d86Aea9
0 ETH
69016032022-05-17 17:42:34681 days ago1652809354
0x8180949a...95d86Aea9
0 ETH
69016032022-05-17 17:42:34681 days ago1652809354
0x8180949a...95d86Aea9
0 ETH
66545512022-04-04 4:38:43725 days ago1649047123
0x8180949a...95d86Aea9
0 ETH
66545512022-04-04 4:38:43725 days ago1649047123
0x8180949a...95d86Aea9
0 ETH
66501092022-04-03 10:07:22726 days ago1648980442
0x8180949a...95d86Aea9
0 ETH
66501092022-04-03 10:07:22726 days ago1648980442
0x8180949a...95d86Aea9
0 ETH
65123102022-03-10 11:36:32750 days ago1646912192
0x8180949a...95d86Aea9
0 ETH
65123102022-03-10 11:36:32750 days ago1646912192
0x8180949a...95d86Aea9
0 ETH
65122952022-03-10 11:32:47750 days ago1646911967
0x8180949a...95d86Aea9
0 ETH
65122952022-03-10 11:32:47750 days ago1646911967
0x8180949a...95d86Aea9
0 ETH
65088952022-03-09 21:22:14750 days ago1646860934
0x8180949a...95d86Aea9
0 ETH
65088952022-03-09 21:22:14750 days ago1646860934
0x8180949a...95d86Aea9
0 ETH
63956232022-02-17 15:28:54770 days ago1645111734
0x8180949a...95d86Aea9
0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TopUpRewardPrograms

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-09-28
*/

// SPDX-License-Identifier: GPL-3.0 AND MIT
// File: contracts/TrustedCaller.sol

// SPDX-FileCopyrightText: 2021 Lido <[email protected]>

pragma solidity ^0.8.4;

/// @author psirex
/// @notice A helper contract contains logic to validate that only a trusted caller has access to certain methods.
/// @dev Trusted caller set once on deployment and can't be changed.
contract TrustedCaller {
    string private constant ERROR_TRUSTED_CALLER_IS_ZERO_ADDRESS = "TRUSTED_CALLER_IS_ZERO_ADDRESS";
    string private constant ERROR_CALLER_IS_FORBIDDEN = "CALLER_IS_FORBIDDEN";

    address public immutable trustedCaller;

    constructor(address _trustedCaller) {
        require(_trustedCaller != address(0), ERROR_TRUSTED_CALLER_IS_ZERO_ADDRESS);
        trustedCaller = _trustedCaller;
    }

    modifier onlyTrustedCaller(address _caller) {
        require(_caller == trustedCaller, ERROR_CALLER_IS_FORBIDDEN);
        _;
    }
}

// File: OpenZeppelin/[email protected]/contracts/access/IAccessControl.sol


pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

// File: OpenZeppelin/[email protected]/contracts/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: OpenZeppelin/[email protected]/contracts/utils/Strings.sol


pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

// File: OpenZeppelin/[email protected]/contracts/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);
}

// File: OpenZeppelin/[email protected]/contracts/utils/introspection/ERC165.sol


pragma solidity ^0.8.0;


/**
 * @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;
    }
}

// File: OpenZeppelin/[email protected]/contracts/access/AccessControl.sol


pragma solidity ^0.8.0;





/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    function _grantRole(bytes32 role, address account) private {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

// File: contracts/RewardProgramsRegistry.sol

// SPDX-FileCopyrightText: 2021 Lido <[email protected]>

pragma solidity ^0.8.4;


/// @author psirex
/// @title Registry of allowed reward programs
/// @notice Stores list of addresses with reward programs
contract RewardProgramsRegistry is AccessControl {
    // -------------
    // EVENTS
    // -------------
    event RewardProgramAdded(address indexed _rewardProgram, string _title);
    event RewardProgramRemoved(address indexed _rewardProgram);

    // -------------
    // ROLES
    // -------------
    bytes32 public constant ADD_REWARD_PROGRAM_ROLE = keccak256("ADD_REWARD_PROGRAM_ROLE");
    bytes32 public constant REMOVE_REWARD_PROGRAM_ROLE = keccak256("REMOVE_REWARD_PROGRAM_ROLE");

    // -------------
    // ERRORS
    // -------------
    string private constant ERROR_REWARD_PROGRAM_ALREADY_ADDED = "REWARD_PROGRAM_ALREADY_ADDED";
    string private constant ERROR_REWARD_PROGRAM_NOT_FOUND = "REWARD_PROGRAM_NOT_FOUND";

    // -------------
    // VARIABLES
    // -------------

    /// @dev List of allowed reward program addresses
    address[] public rewardPrograms;

    // Position of the reward program in the `rewardPrograms` array,
    // plus 1 because index 0 means a value is not in the set.
    mapping(address => uint256) private rewardProgramIndices;

    // -------------
    // CONSTRUCTOR
    // -------------

    /// @param _admin Address which will be granted with role DEFAULT_ADMIN_ROLE
    /// @param _addRewardProgramRoleHolders List of addresses which will be
    ///     granted with role ADD_REWARD_PROGRAM_ROLE
    /// @param _removeRewardProgramRoleHolders List of addresses which will
    ///     be granted with role REMOVE_REWARD_PROGRAM_ROLE
    constructor(
        address _admin,
        address[] memory _addRewardProgramRoleHolders,
        address[] memory _removeRewardProgramRoleHolders
    ) {
        _setupRole(DEFAULT_ADMIN_ROLE, _admin);
        for (uint256 i = 0; i < _addRewardProgramRoleHolders.length; i++) {
            _setupRole(ADD_REWARD_PROGRAM_ROLE, _addRewardProgramRoleHolders[i]);
        }
        for (uint256 i = 0; i < _removeRewardProgramRoleHolders.length; i++) {
            _setupRole(REMOVE_REWARD_PROGRAM_ROLE, _removeRewardProgramRoleHolders[i]);
        }
    }

    // -------------
    // EXTERNAL METHODS
    // -------------

    /// @notice Adds address to list of allowed reward programs
    function addRewardProgram(address _rewardProgram, string memory _title)
        external
        onlyRole(ADD_REWARD_PROGRAM_ROLE)
    {
        require(rewardProgramIndices[_rewardProgram] == 0, ERROR_REWARD_PROGRAM_ALREADY_ADDED);

        rewardPrograms.push(_rewardProgram);
        rewardProgramIndices[_rewardProgram] = rewardPrograms.length;
        emit RewardProgramAdded(_rewardProgram, _title);
    }

    /// @notice Removes address from list of allowed reward programs
    /// @dev To delete a reward program from the rewardPrograms array in O(1), we swap the element to delete with the last one in
    /// the array, and then remove the last element (sometimes called as 'swap and pop').
    function removeRewardProgram(address _rewardProgram)
        external
        onlyRole(REMOVE_REWARD_PROGRAM_ROLE)
    {
        uint256 index = _getRewardProgramIndex(_rewardProgram);
        uint256 lastIndex = rewardPrograms.length - 1;

        if (index != lastIndex) {
            address lastRewardProgram = rewardPrograms[lastIndex];
            rewardPrograms[index] = lastRewardProgram;
            rewardProgramIndices[lastRewardProgram] = index + 1;
        }

        rewardPrograms.pop();
        delete rewardProgramIndices[_rewardProgram];
        emit RewardProgramRemoved(_rewardProgram);
    }

    /// @notice Returns if passed address are listed as reward program in the registry
    function isRewardProgram(address _maybeRewardProgram) external view returns (bool) {
        return rewardProgramIndices[_maybeRewardProgram] > 0;
    }

    /// @notice Returns current list of reward programs
    function getRewardPrograms() external view returns (address[] memory) {
        return rewardPrograms;
    }

    // ------------------
    // PRIVATE METHODS
    // ------------------

    function _getRewardProgramIndex(address _evmScriptFactory)
        private
        view
        returns (uint256 _index)
    {
        _index = rewardProgramIndices[_evmScriptFactory];
        require(_index > 0, ERROR_REWARD_PROGRAM_NOT_FOUND);
        _index -= 1;
    }
}

// File: contracts/interfaces/IFinance.sol

// SPDX-FileCopyrightText: 2021 Lido <[email protected]>

pragma solidity ^0.8.4;

/// @author psirex
/// @notice Interface of method from Aragon's Finance contract to create a new payment
interface IFinance {
    function newImmediatePayment(
        address _token,
        address _receiver,
        uint256 _amount,
        string memory _reference
    ) external;
}

// File: contracts/libraries/EVMScriptCreator.sol

// SPDX-FileCopyrightText: 2021 Lido <[email protected]>

pragma solidity ^0.8.4;

/// @author psirex
/// @notice Contains methods for convenient creation
/// of EVMScripts in EVMScript factories contracts
library EVMScriptCreator {
    // Id of default CallsScript Aragon's executor.
    bytes4 private constant SPEC_ID = hex"00000001";

    /// @notice Encodes one method call as EVMScript
    function createEVMScript(
        address _to,
        bytes4 _methodId,
        bytes memory _evmScriptCallData
    ) internal pure returns (bytes memory _commands) {
        return
            abi.encodePacked(
                SPEC_ID,
                _to,
                uint32(_evmScriptCallData.length) + 4,
                _methodId,
                _evmScriptCallData
            );
    }

    /// @notice Encodes multiple calls of the same method on one contract as EVMScript
    function createEVMScript(
        address _to,
        bytes4 _methodId,
        bytes[] memory _evmScriptCallData
    ) internal pure returns (bytes memory _evmScript) {
        for (uint256 i = 0; i < _evmScriptCallData.length; ++i) {
            _evmScript = bytes.concat(
                _evmScript,
                abi.encodePacked(
                    _to,
                    uint32(_evmScriptCallData[i].length) + 4,
                    _methodId,
                    _evmScriptCallData[i]
                )
            );
        }
        _evmScript = bytes.concat(SPEC_ID, _evmScript);
    }

    /// @notice Encodes multiple calls to different methods within the same contract as EVMScript
    function createEVMScript(
        address _to,
        bytes4[] memory _methodIds,
        bytes[] memory _evmScriptCallData
    ) internal pure returns (bytes memory _evmScript) {
        require(_methodIds.length == _evmScriptCallData.length, "LENGTH_MISMATCH");

        for (uint256 i = 0; i < _methodIds.length; ++i) {
            _evmScript = bytes.concat(
                _evmScript,
                abi.encodePacked(
                    _to,
                    uint32(_evmScriptCallData[i].length) + 4,
                    _methodIds[i],
                    _evmScriptCallData[i]
                )
            );
        }
        _evmScript = bytes.concat(SPEC_ID, _evmScript);
    }

    /// @notice Encodes multiple calls to different contracts as EVMScript
    function createEVMScript(
        address[] memory _to,
        bytes4[] memory _methodIds,
        bytes[] memory _evmScriptCallData
    ) internal pure returns (bytes memory _evmScript) {
        require(_to.length == _methodIds.length, "LENGTH_MISMATCH");
        require(_to.length == _evmScriptCallData.length, "LENGTH_MISMATCH");

        for (uint256 i = 0; i < _to.length; ++i) {
            _evmScript = bytes.concat(
                _evmScript,
                abi.encodePacked(
                    _to[i],
                    uint32(_evmScriptCallData[i].length) + 4,
                    _methodIds[i],
                    _evmScriptCallData[i]
                )
            );
        }
        _evmScript = bytes.concat(SPEC_ID, _evmScript);
    }
}

// File: contracts/interfaces/IEVMScriptFactory.sol

// SPDX-FileCopyrightText: 2021 Lido <[email protected]>

pragma solidity ^0.8.4;

/// @author psirex
/// @notice Interface which every EVMScript factory used in EasyTrack contract has to implement
interface IEVMScriptFactory {
    function createEVMScript(address _creator, bytes memory _evmScriptCallData)
        external
        returns (bytes memory);
}

// File: contracts/EVMScriptFactories/TopUpRewardPrograms.sol

// SPDX-FileCopyrightText: 2021 Lido <[email protected]>

pragma solidity ^0.8.4;






/// @author psirex
/// @notice Creates EVMScript to top up balances of reward programs
contract TopUpRewardPrograms is TrustedCaller, IEVMScriptFactory {
    // -------------
    // ERRORS
    // -------------
    string private constant ERROR_LENGTH_MISMATCH = "LENGTH_MISMATCH";
    string private constant ERROR_EMPTY_DATA = "EMPTY_DATA";
    string private constant ERROR_ZERO_AMOUNT = "ZERO_AMOUNT";
    string private constant ERROR_REWARD_PROGRAM_NOT_ALLOWED = "REWARD_PROGRAM_NOT_ALLOWED";

    // -------------
    // VARIABLES
    // -------------

    /// @notice Address of Aragon's Finance contract
    IFinance public immutable finance;

    /// @notice Address of reward token
    address public immutable rewardToken;

    /// @notice Address of RewardProgramsRegistry
    RewardProgramsRegistry public immutable rewardProgramsRegistry;

    // -------------
    // CONSTRUCTOR
    // -------------

    constructor(
        address _trustedCaller,
        address _rewardProgramsRegistry,
        address _finance,
        address _rewardToken
    ) TrustedCaller(_trustedCaller) {
        finance = IFinance(_finance);
        rewardToken = _rewardToken;
        rewardProgramsRegistry = RewardProgramsRegistry(_rewardProgramsRegistry);
    }

    // -------------
    // EXTERNAL METHODS
    // -------------

    /// @notice Creates EVMScript to top up balances of reward programs
    /// @param _creator Address who creates EVMScript
    /// @param _evmScriptCallData Encoded tuple: (address[] _rewardPrograms, uint256[] _amounts) where
    /// _rewardPrograms - addresses of reward programs to top up
    /// _amounts - corresponding amount of tokens to transfer
    function createEVMScript(address _creator, bytes memory _evmScriptCallData)
        external
        view
        override
        onlyTrustedCaller(_creator)
        returns (bytes memory)
    {
        (address[] memory rewardPrograms, uint256[] memory amounts) =
            _decodeEVMScriptCallData(_evmScriptCallData);

        _validateEVMScriptCallData(rewardPrograms, amounts);

        bytes[] memory evmScriptsCalldata = new bytes[](rewardPrograms.length);
        for (uint256 i = 0; i < rewardPrograms.length; ++i) {
            evmScriptsCalldata[i] = abi.encode(
                rewardToken,
                rewardPrograms[i],
                amounts[i],
                "Reward program top up"
            );
        }
        return
            EVMScriptCreator.createEVMScript(
                address(finance),
                finance.newImmediatePayment.selector,
                evmScriptsCalldata
            );
    }

    /// @notice Decodes call data used by createEVMScript method
    /// @param _evmScriptCallData Encoded tuple: (address[] _rewardPrograms, uint256[] _amounts) where
    /// _rewardPrograms - addresses of reward programs to top up
    /// _amounts - corresponding amount of tokens to transfer
    /// @return _rewardPrograms Addresses of reward programs to top up
    /// @return _amounts Amounts of tokens to transfer
    function decodeEVMScriptCallData(bytes memory _evmScriptCallData)
        external
        pure
        returns (address[] memory _rewardPrograms, uint256[] memory _amounts)
    {
        return _decodeEVMScriptCallData(_evmScriptCallData);
    }

    // ------------------
    // PRIVATE METHODS
    // ------------------

    function _validateEVMScriptCallData(address[] memory _rewardPrograms, uint256[] memory _amounts)
        private
        view
    {
        require(_rewardPrograms.length == _amounts.length, ERROR_LENGTH_MISMATCH);
        require(_rewardPrograms.length > 0, ERROR_EMPTY_DATA);
        for (uint256 i = 0; i < _rewardPrograms.length; ++i) {
            require(_amounts[i] > 0, ERROR_ZERO_AMOUNT);
            require(
                rewardProgramsRegistry.isRewardProgram(_rewardPrograms[i]),
                ERROR_REWARD_PROGRAM_NOT_ALLOWED
            );
        }
    }

    function _decodeEVMScriptCallData(bytes memory _evmScriptCallData)
        private
        pure
        returns (address[] memory _rewardPrograms, uint256[] memory _amounts)
    {
        return abi.decode(_evmScriptCallData, (address[], uint256[]));
    }
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_trustedCaller","type":"address"},{"internalType":"address","name":"_rewardProgramsRegistry","type":"address"},{"internalType":"address","name":"_finance","type":"address"},{"internalType":"address","name":"_rewardToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"_creator","type":"address"},{"internalType":"bytes","name":"_evmScriptCallData","type":"bytes"}],"name":"createEVMScript","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_evmScriptCallData","type":"bytes"}],"name":"decodeEVMScriptCallData","outputs":[{"internalType":"address[]","name":"_rewardPrograms","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"finance","outputs":[{"internalType":"contract IFinance","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardProgramsRegistry","outputs":[{"internalType":"contract RewardProgramsRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trustedCaller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

61010060405234801561001157600080fd5b5060405162000dc638038062000dc6833981016040819052610032916100e6565b60408051808201909152601e81527f545255535445445f43414c4c45525f49535f5a45524f5f414444524553530000602082015284906001600160a01b0382166100985760405162461bcd60e51b815260040161008f919061013a565b60405180910390fd5b506001600160601b0319606091821b811660805292811b831660a05290811b821660c0529190911b1660e0525061018f565b80516001600160a01b03811681146100e157600080fd5b919050565b600080600080608085870312156100fc57600080fd5b610105856100ca565b9350610113602086016100ca565b9250610121604086016100ca565b915061012f606086016100ca565b905092959194509250565b600060208083528351808285015260005b818110156101675785810183015185820160400152820161014b565b81811115610179576000604083870101525b50601f01601f1916929092016040019392505050565b60805160601c60a05160601c60c05160601c60e05160601c610bd8620001ee6000396000818160d701526104c001526000818161011f015261027c01526000818160b00152610370015260008181606c015261017b0152610bd86000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c8063268f076014610067578063313b7b19146100ab5780633f052ae9146100d2578063ecf7c690146100f9578063f7c618c11461011a578063fea21c9c14610141575b600080fd5b61008e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61008e7f000000000000000000000000000000000000000000000000000000000000000081565b61008e7f000000000000000000000000000000000000000000000000000000000000000081565b61010c6101073660046108de565b610161565b6040516100a29291906109ff565b61008e7f000000000000000000000000000000000000000000000000000000000000000081565b61015461014f3660046107a3565b610176565b6040516100a29190610a76565b60608061016d836103a8565b91509150915091565b6060827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316146040518060400160405280601381526020017221a0a62622a92fa4a9afa327a92124a22222a760691b815250906102015760405162461bcd60e51b81526004016101f89190610a76565b60405180910390fd5b5060008061020e856103a8565b9150915061021c82826103bf565b6000825167ffffffffffffffff81111561023857610238610b74565b60405190808252806020026020018201604052801561026b57816020015b60608152602001906001900390816102565790505b50905060005b835181101561036a577f00000000000000000000000000000000000000000000000000000000000000008482815181106102ad576102ad610b5e565b60200260200101518483815181106102c7576102c7610b5e565b602002602001015160405160200161032d939291906001600160a01b03938416815291909216602082015260408101919091526080606082018190526015908201527405265776172642070726f6772616d20746f7020757605c1b60a082015260c00190565b60405160208183030381529060405282828151811061034e5761034e610b5e565b60200260200101819052508061036390610b2d565b9050610271565b5061039d7f0000000000000000000000000000000000000000000000000000000000000000637b1b242360e11b836105ec565b979650505050505050565b6060808280602001905181019061016d91906107f3565b80518251146040518060400160405280600f81526020016e0988a9c8ea890be9a92a69a82a8869608b1b8152509061040a5760405162461bcd60e51b81526004016101f89190610a76565b5060008251116040518060400160405280600a815260200169454d5054595f4441544160b01b815250906104515760405162461bcd60e51b81526004016101f89190610a76565b5060005b82518110156105e757600082828151811061047257610472610b5e565b6020026020010151116040518060400160405280600b81526020016a16915493d7d05353d5539560aa1b815250906104bd5760405162461bcd60e51b81526004016101f89190610a76565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639525581c8483815181106104ff576104ff610b5e565b60200260200101516040518263ffffffff1660e01b815260040161053291906001600160a01b0391909116815260200190565b60206040518083038186803b15801561054a57600080fd5b505afa15801561055e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058291906108b5565b6040518060400160405280601a81526020017f5245574152445f50524f4752414d5f4e4f545f414c4c4f574544000000000000815250906105d65760405162461bcd60e51b81526004016101f89190610a76565b506105e081610b2d565b9050610455565b505050565b606060005b825181101561069157818584838151811061060e5761060e610b5e565b60200260200101515160046106239190610ade565b8686858151811061063657610636610b5e565b60200260200101516040516020016106519493929190610947565b60408051601f198184030181529082905261066f92916020016109d0565b60405160208183030381529060405291508061068a90610b2d565b90506105f1565b50600160e01b816040516020016106a992919061099f565b60405160208183030381529060405290509392505050565b600082601f8301126106d257600080fd5b815160206106e76106e283610aba565b610a89565b80838252828201915082860187848660051b890101111561070757600080fd5b60005b858110156107265781518452928401929084019060010161070a565b5090979650505050505050565b600082601f83011261074457600080fd5b813567ffffffffffffffff81111561075e5761075e610b74565b610771601f8201601f1916602001610a89565b81815284602083860101111561078657600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156107b657600080fd5b82356107c181610b8a565b9150602083013567ffffffffffffffff8111156107dd57600080fd5b6107e985828601610733565b9150509250929050565b6000806040838503121561080657600080fd5b825167ffffffffffffffff8082111561081e57600080fd5b818501915085601f83011261083257600080fd5b815160206108426106e283610aba565b8083825282820191508286018a848660051b890101111561086257600080fd5b600096505b8487101561088e57805161087a81610b8a565b835260019690960195918301918301610867565b50918801519196509093505050808211156108a857600080fd5b506107e9858286016106c1565b6000602082840312156108c757600080fd5b815180151581146108d757600080fd5b9392505050565b6000602082840312156108f057600080fd5b813567ffffffffffffffff81111561090757600080fd5b61091384828501610733565b949350505050565b60008151808452610933816020860160208601610afd565b601f01601f19169290920160200192915050565b6bffffffffffffffffffffffff19606086901b1681526001600160e01b031960e085901b8116601483015283166018820152815160009061098f81601c850160208701610afd565b91909101601c0195945050505050565b6001600160e01b03198316815281516000906109c2816004850160208701610afd565b919091016004019392505050565b600083516109e2818460208801610afd565b8351908301906109f6818360208801610afd565b01949350505050565b604080825283519082018190526000906020906060840190828701845b82811015610a415781516001600160a01b031684529284019290840190600101610a1c565b5050508381038285015284518082528583019183019060005b8181101561072657835183529284019291840191600101610a5a565b6020815260006108d7602083018461091b565b604051601f8201601f1916810167ffffffffffffffff81118282101715610ab257610ab2610b74565b604052919050565b600067ffffffffffffffff821115610ad457610ad4610b74565b5060051b60200190565b600063ffffffff8083168185168083038211156109f6576109f6610b48565b60005b83811015610b18578181015183820152602001610b00565b83811115610b27576000848401525b50505050565b6000600019821415610b4157610b41610b48565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610b9f57600080fd5b5056fea26469706673582212202917cd3f5a591a57d448cc6d3fcf34059fa861f3547a324b89e05e4f35e0b79564736f6c634300080600330000000000000000000000004ec7b04fccd45482da61984b5415798d02223f8800000000000000000000000028a08f61ae129d0d8bd4380ae5647e7add0527ca00000000000000000000000075c7b1d23f1cad7fb4d60281d7069e46440bc17900000000000000000000000056340274fb5a72af1a3c6609061c451de7961bd4

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100625760003560e01c8063268f076014610067578063313b7b19146100ab5780633f052ae9146100d2578063ecf7c690146100f9578063f7c618c11461011a578063fea21c9c14610141575b600080fd5b61008e7f0000000000000000000000004ec7b04fccd45482da61984b5415798d02223f8881565b6040516001600160a01b0390911681526020015b60405180910390f35b61008e7f00000000000000000000000075c7b1d23f1cad7fb4d60281d7069e46440bc17981565b61008e7f00000000000000000000000028a08f61ae129d0d8bd4380ae5647e7add0527ca81565b61010c6101073660046108de565b610161565b6040516100a29291906109ff565b61008e7f00000000000000000000000056340274fb5a72af1a3c6609061c451de7961bd481565b61015461014f3660046107a3565b610176565b6040516100a29190610a76565b60608061016d836103a8565b91509150915091565b6060827f0000000000000000000000004ec7b04fccd45482da61984b5415798d02223f886001600160a01b0316816001600160a01b0316146040518060400160405280601381526020017221a0a62622a92fa4a9afa327a92124a22222a760691b815250906102015760405162461bcd60e51b81526004016101f89190610a76565b60405180910390fd5b5060008061020e856103a8565b9150915061021c82826103bf565b6000825167ffffffffffffffff81111561023857610238610b74565b60405190808252806020026020018201604052801561026b57816020015b60608152602001906001900390816102565790505b50905060005b835181101561036a577f00000000000000000000000056340274fb5a72af1a3c6609061c451de7961bd48482815181106102ad576102ad610b5e565b60200260200101518483815181106102c7576102c7610b5e565b602002602001015160405160200161032d939291906001600160a01b03938416815291909216602082015260408101919091526080606082018190526015908201527405265776172642070726f6772616d20746f7020757605c1b60a082015260c00190565b60405160208183030381529060405282828151811061034e5761034e610b5e565b60200260200101819052508061036390610b2d565b9050610271565b5061039d7f00000000000000000000000075c7b1d23f1cad7fb4d60281d7069e46440bc179637b1b242360e11b836105ec565b979650505050505050565b6060808280602001905181019061016d91906107f3565b80518251146040518060400160405280600f81526020016e0988a9c8ea890be9a92a69a82a8869608b1b8152509061040a5760405162461bcd60e51b81526004016101f89190610a76565b5060008251116040518060400160405280600a815260200169454d5054595f4441544160b01b815250906104515760405162461bcd60e51b81526004016101f89190610a76565b5060005b82518110156105e757600082828151811061047257610472610b5e565b6020026020010151116040518060400160405280600b81526020016a16915493d7d05353d5539560aa1b815250906104bd5760405162461bcd60e51b81526004016101f89190610a76565b507f00000000000000000000000028a08f61ae129d0d8bd4380ae5647e7add0527ca6001600160a01b0316639525581c8483815181106104ff576104ff610b5e565b60200260200101516040518263ffffffff1660e01b815260040161053291906001600160a01b0391909116815260200190565b60206040518083038186803b15801561054a57600080fd5b505afa15801561055e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058291906108b5565b6040518060400160405280601a81526020017f5245574152445f50524f4752414d5f4e4f545f414c4c4f574544000000000000815250906105d65760405162461bcd60e51b81526004016101f89190610a76565b506105e081610b2d565b9050610455565b505050565b606060005b825181101561069157818584838151811061060e5761060e610b5e565b60200260200101515160046106239190610ade565b8686858151811061063657610636610b5e565b60200260200101516040516020016106519493929190610947565b60408051601f198184030181529082905261066f92916020016109d0565b60405160208183030381529060405291508061068a90610b2d565b90506105f1565b50600160e01b816040516020016106a992919061099f565b60405160208183030381529060405290509392505050565b600082601f8301126106d257600080fd5b815160206106e76106e283610aba565b610a89565b80838252828201915082860187848660051b890101111561070757600080fd5b60005b858110156107265781518452928401929084019060010161070a565b5090979650505050505050565b600082601f83011261074457600080fd5b813567ffffffffffffffff81111561075e5761075e610b74565b610771601f8201601f1916602001610a89565b81815284602083860101111561078657600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156107b657600080fd5b82356107c181610b8a565b9150602083013567ffffffffffffffff8111156107dd57600080fd5b6107e985828601610733565b9150509250929050565b6000806040838503121561080657600080fd5b825167ffffffffffffffff8082111561081e57600080fd5b818501915085601f83011261083257600080fd5b815160206108426106e283610aba565b8083825282820191508286018a848660051b890101111561086257600080fd5b600096505b8487101561088e57805161087a81610b8a565b835260019690960195918301918301610867565b50918801519196509093505050808211156108a857600080fd5b506107e9858286016106c1565b6000602082840312156108c757600080fd5b815180151581146108d757600080fd5b9392505050565b6000602082840312156108f057600080fd5b813567ffffffffffffffff81111561090757600080fd5b61091384828501610733565b949350505050565b60008151808452610933816020860160208601610afd565b601f01601f19169290920160200192915050565b6bffffffffffffffffffffffff19606086901b1681526001600160e01b031960e085901b8116601483015283166018820152815160009061098f81601c850160208701610afd565b91909101601c0195945050505050565b6001600160e01b03198316815281516000906109c2816004850160208701610afd565b919091016004019392505050565b600083516109e2818460208801610afd565b8351908301906109f6818360208801610afd565b01949350505050565b604080825283519082018190526000906020906060840190828701845b82811015610a415781516001600160a01b031684529284019290840190600101610a1c565b5050508381038285015284518082528583019183019060005b8181101561072657835183529284019291840191600101610a5a565b6020815260006108d7602083018461091b565b604051601f8201601f1916810167ffffffffffffffff81118282101715610ab257610ab2610b74565b604052919050565b600067ffffffffffffffff821115610ad457610ad4610b74565b5060051b60200190565b600063ffffffff8083168185168083038211156109f6576109f6610b48565b60005b83811015610b18578181015183820152602001610b00565b83811115610b27576000848401525b50505050565b6000600019821415610b4157610b41610b48565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610b9f57600080fd5b5056fea26469706673582212202917cd3f5a591a57d448cc6d3fcf34059fa861f3547a324b89e05e4f35e0b79564736f6c63430008060033

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

0000000000000000000000004ec7b04fccd45482da61984b5415798d02223f8800000000000000000000000028a08f61ae129d0d8bd4380ae5647e7add0527ca00000000000000000000000075c7b1d23f1cad7fb4d60281d7069e46440bc17900000000000000000000000056340274fb5a72af1a3c6609061c451de7961bd4

-----Decoded View---------------
Arg [0] : _trustedCaller (address): 0x4ec7B04Fccd45482Da61984b5415798D02223F88
Arg [1] : _rewardProgramsRegistry (address): 0x28a08f61AE129d0d8BD4380Ae5647e7Add0527ca
Arg [2] : _finance (address): 0x75c7b1D23f1cad7Fb4D60281d7069E46440BC179
Arg [3] : _rewardToken (address): 0x56340274fB5a72af1A3C6609061c451De7961Bd4

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000004ec7b04fccd45482da61984b5415798d02223f88
Arg [1] : 00000000000000000000000028a08f61ae129d0d8bd4380ae5647e7add0527ca
Arg [2] : 00000000000000000000000075c7b1d23f1cad7fb4d60281d7069e46440bc179
Arg [3] : 00000000000000000000000056340274fb5a72af1a3c6609061c451de7961bd4


Deployed Bytecode Sourcemap

24969:4248:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;587:38;;;;;;;;-1:-1:-1;;;;;5382:32:1;;;5364:51;;5352:2;5337:18;587:38:0;;;;;;;;25512:33;;;;;25691:62;;;;;28017:252;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;25595:36::-;;;;;26617:965;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;28017:252::-;28133:32;28167:25;28217:44;28242:18;28217:24;:44::i;:::-;28210:51;;;;28017:252;;;:::o;26617:965::-;26798:12;26770:8;887:13;-1:-1:-1;;;;;876:24:0;:7;-1:-1:-1;;;;;876:24:0;;902:25;;;;;;;;;;;;;-1:-1:-1;;;902:25:0;;;868:60;;;;;-1:-1:-1;;;868:60:0;;;;;;;;:::i;:::-;;;;;;;;;;26829:31:::1;26862:24:::0;26903:44:::1;26928:18;26903:24;:44::i;:::-;26828:119;;;;26960:51;26987:14;27003:7;26960:26;:51::i;:::-;27024:33;27072:14;:21;27060:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27024:70;;27110:9;27105:265;27129:14;:21;27125:1;:25;27105:265;;;27225:11;27255:14;27270:1;27255:17;;;;;;;;:::i;:::-;;;;;;;27291:7;27299:1;27291:10;;;;;;;;:::i;:::-;;;;;;;27196:162;;;;;;;;;-1:-1:-1::0;;;;;5750:15:1;;;5732:34;;5802:15;;;;5797:2;5782:18;;5775:43;5849:2;5834:18;;5827:34;;;;5897:3;5892:2;5877:18;;5870:31;;;5938:2;5917:19;;;5910:31;-1:-1:-1;;;5712:3:1;5957:19;;5950:52;6034:3;6019:19;;5684:360;27196:162:0::1;;;;;;;;;;;;;27172:18;27191:1;27172:21;;;;;;;;:::i;:::-;;;;;;:186;;;;27152:3;;;;:::i;:::-;;;27105:265;;;-1:-1:-1::0;27400:174:0::1;27459:7;-1:-1:-1::0;;;27541:18:0;27400:32:::1;:174::i;:::-;27380:194:::0;26617:965;-1:-1:-1;;;;;;;26617:965:0:o;28952:262::-;29068:32;29102:25;29163:18;29152:54;;;;;;;;;;;;:::i;28357:587::-;28535:8;:15;28509;:22;:41;28552:21;;;;;;;;;;;;;-1:-1:-1;;;28552:21:0;;;28501:73;;;;;-1:-1:-1;;;28501:73:0;;;;;;;;:::i;:::-;;28618:1;28593:15;:22;:26;28621:16;;;;;;;;;;;;;-1:-1:-1;;;28621:16:0;;;28585:53;;;;;-1:-1:-1;;;28585:53:0;;;;;;;;:::i;:::-;;28654:9;28649:288;28673:15;:22;28669:1;:26;28649:288;;;28739:1;28725:8;28734:1;28725:11;;;;;;;;:::i;:::-;;;;;;;:15;28742:17;;;;;;;;;;;;;-1:-1:-1;;;28742:17:0;;;28717:43;;;;;-1:-1:-1;;;28717:43:0;;;;;;;;:::i;:::-;;28801:22;-1:-1:-1;;;;;28801:38:0;;28840:15;28856:1;28840:18;;;;;;;;:::i;:::-;;;;;;;28801:58;;;;;;;;;;;;;;-1:-1:-1;;;;;5382:32:1;;;;5364:51;;5352:2;5337:18;;5319:102;28801:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28878:32;;;;;;;;;;;;;;;;;28775:150;;;;;-1:-1:-1;;;28775:150:0;;;;;;;;:::i;:::-;-1:-1:-1;28697:3:0;;;:::i;:::-;;;28649:288;;;;28357:587;;:::o;21992:619::-;22140:23;22181:9;22176:371;22200:18;:25;22196:1;:29;22176:371;;;22291:10;22359:3;22392:18;22411:1;22392:21;;;;;;;;:::i;:::-;;;;;;;:28;22424:1;22385:40;;;;:::i;:::-;22448:9;22480:18;22499:1;22480:21;;;;;;;;:::i;:::-;;;;;;;22320:200;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;22320:200:0;;;;;;;;;;22260:275;;;22320:200;22260:275;;:::i;:::-;;;;;;;;;;;;;22247:288;;22227:3;;;;:::i;:::-;;;22176:371;;;;-1:-1:-1;;;22592:10:0;22570:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;22557:46;;21992:619;;;;;:::o;14:670:1:-;79:5;132:3;125:4;117:6;113:17;109:27;99:2;;150:1;147;140:12;99:2;179:6;173:13;205:4;229:60;245:43;285:2;245:43;:::i;:::-;229:60;:::i;:::-;311:3;335:2;330:3;323:15;363:2;358:3;354:12;347:19;;398:2;390:6;386:15;450:3;445:2;439;436:1;432:10;424:6;420:23;416:32;413:41;410:2;;;467:1;464;457:12;410:2;489:1;499:156;513:2;510:1;507:9;499:156;;;570:10;;558:23;;601:12;;;;633;;;;531:1;524:9;499:156;;;-1:-1:-1;673:5:1;;89:595;-1:-1:-1;;;;;;;89:595:1:o;689:530::-;731:5;784:3;777:4;769:6;765:17;761:27;751:2;;802:1;799;792:12;751:2;838:6;825:20;864:18;860:2;857:26;854:2;;;886:18;;:::i;:::-;930:55;973:2;954:13;;-1:-1:-1;;950:27:1;979:4;946:38;930:55;:::i;:::-;1010:2;1001:7;994:19;1056:3;1049:4;1044:2;1036:6;1032:15;1028:26;1025:35;1022:2;;;1073:1;1070;1063:12;1022:2;1138;1131:4;1123:6;1119:17;1112:4;1103:7;1099:18;1086:55;1186:1;1161:16;;;1179:4;1157:27;1150:38;;;;1165:7;741:478;-1:-1:-1;;;741:478:1:o;1224:455::-;1301:6;1309;1362:2;1350:9;1341:7;1337:23;1333:32;1330:2;;;1378:1;1375;1368:12;1330:2;1417:9;1404:23;1436:31;1461:5;1436:31;:::i;:::-;1486:5;-1:-1:-1;1542:2:1;1527:18;;1514:32;1569:18;1558:30;;1555:2;;;1601:1;1598;1591:12;1555:2;1624:49;1665:7;1656:6;1645:9;1641:22;1624:49;:::i;:::-;1614:59;;;1320:359;;;;;:::o;1684:1220::-;1813:6;1821;1874:2;1862:9;1853:7;1849:23;1845:32;1842:2;;;1890:1;1887;1880:12;1842:2;1923:9;1917:16;1952:18;1993:2;1985:6;1982:14;1979:2;;;2009:1;2006;1999:12;1979:2;2047:6;2036:9;2032:22;2022:32;;2092:7;2085:4;2081:2;2077:13;2073:27;2063:2;;2114:1;2111;2104:12;2063:2;2143;2137:9;2165:4;2189:60;2205:43;2245:2;2205:43;:::i;2189:60::-;2271:3;2295:2;2290:3;2283:15;2323:2;2318:3;2314:12;2307:19;;2354:2;2350;2346:11;2402:7;2397:2;2391;2388:1;2384:10;2380:2;2376:19;2372:28;2369:41;2366:2;;;2423:1;2420;2413:12;2366:2;2445:1;2436:10;;2455:231;2469:2;2466:1;2463:9;2455:231;;;2533:3;2527:10;2550:31;2575:5;2550:31;:::i;:::-;2594:18;;2487:1;2480:9;;;;;2632:12;;;;2664;;2455:231;;;-1:-1:-1;2741:18:1;;;2735:25;2705:5;;-1:-1:-1;2735:25:1;;-1:-1:-1;;;2772:16:1;;;2769:2;;;2801:1;2798;2791:12;2769:2;;2824:74;2890:7;2879:8;2868:9;2864:24;2824:74;:::i;2909:277::-;2976:6;3029:2;3017:9;3008:7;3004:23;3000:32;2997:2;;;3045:1;3042;3035:12;2997:2;3077:9;3071:16;3130:5;3123:13;3116:21;3109:5;3106:32;3096:2;;3152:1;3149;3142:12;3096:2;3175:5;2987:199;-1:-1:-1;;;2987:199:1:o;3191:320::-;3259:6;3312:2;3300:9;3291:7;3287:23;3283:32;3280:2;;;3328:1;3325;3318:12;3280:2;3368:9;3355:23;3401:18;3393:6;3390:30;3387:2;;;3433:1;3430;3423:12;3387:2;3456:49;3497:7;3488:6;3477:9;3473:22;3456:49;:::i;:::-;3446:59;3270:241;-1:-1:-1;;;;3270:241:1:o;3516:257::-;3557:3;3595:5;3589:12;3622:6;3617:3;3610:19;3638:63;3694:6;3687:4;3682:3;3678:14;3671:4;3664:5;3660:16;3638:63;:::i;:::-;3755:2;3734:15;-1:-1:-1;;3730:29:1;3721:39;;;;3762:4;3717:50;;3565:208;-1:-1:-1;;3565:208:1:o;3778:588::-;-1:-1:-1;;4025:2:1;4021:15;;;4017:53;4005:66;;-1:-1:-1;;;;;;4094:3:1;4144:16;;;4140:25;;4135:2;4126:12;;4119:47;4196:15;;4191:2;4182:12;;4175:37;4235:13;;-1:-1:-1;;4257:62:1;4235:13;4307:2;4298:12;;4291:4;4279:17;;4257:62;:::i;:::-;4339:16;;;;4357:2;4335:25;;3995:371;-1:-1:-1;;;;;3995:371:1:o;4371:::-;-1:-1:-1;;;;;;4556:33:1;;4544:46;;4613:13;;4526:3;;4635:61;4613:13;4685:1;4676:11;;4669:4;4657:17;;4635:61;:::i;:::-;4716:16;;;;4734:1;4712:24;;4534:208;-1:-1:-1;;;4534:208:1:o;4747:466::-;4922:3;4960:6;4954:13;4976:53;5022:6;5017:3;5010:4;5002:6;4998:17;4976:53;:::i;:::-;5092:13;;5051:16;;;;5114:57;5092:13;5051:16;5148:4;5136:17;;5114:57;:::i;:::-;5187:20;;4930:283;-1:-1:-1;;;;4930:283:1:o;6049:1178::-;6317:2;6329:21;;;6399:13;;6302:18;;;6421:22;;;6269:4;;6496;;6474:2;6459:18;;;6523:15;;;6269:4;6566:195;6580:6;6577:1;6574:13;6566:195;;;6645:13;;-1:-1:-1;;;;;6641:39:1;6629:52;;6701:12;;;;6736:15;;;;6677:1;6595:9;6566:195;;;-1:-1:-1;;;6797:19:1;;;6777:18;;;6770:47;6867:13;;6889:21;;;6965:15;;;;6928:12;;;7000:1;7010:189;7026:8;7021:3;7018:17;7010:189;;;7095:15;;7081:30;;7172:17;;;;7133:14;;;;7054:1;7045:11;7010:189;;7232:217;7379:2;7368:9;7361:21;7342:4;7399:44;7439:2;7428:9;7424:18;7416:6;7399:44;:::i;8140:275::-;8211:2;8205:9;8276:2;8257:13;;-1:-1:-1;;8253:27:1;8241:40;;8311:18;8296:34;;8332:22;;;8293:62;8290:2;;;8358:18;;:::i;:::-;8394:2;8387:22;8185:230;;-1:-1:-1;8185:230:1:o;8420:183::-;8480:4;8513:18;8505:6;8502:30;8499:2;;;8535:18;;:::i;:::-;-1:-1:-1;8580:1:1;8576:14;8592:4;8572:25;;8489:114::o;8608:228::-;8647:3;8675:10;8712:2;8709:1;8705:10;8742:2;8739:1;8735:10;8773:3;8769:2;8765:12;8760:3;8757:21;8754:2;;;8781:18;;:::i;8841:258::-;8913:1;8923:113;8937:6;8934:1;8931:13;8923:113;;;9013:11;;;9007:18;8994:11;;;8987:39;8959:2;8952:10;8923:113;;;9054:6;9051:1;9048:13;9045:2;;;9089:1;9080:6;9075:3;9071:16;9064:27;9045:2;;8894:205;;;:::o;9104:135::-;9143:3;-1:-1:-1;;9164:17:1;;9161:2;;;9184:18;;:::i;:::-;-1:-1:-1;9231:1:1;9220:13;;9151:88::o;9244:127::-;9305:10;9300:3;9296:20;9293:1;9286:31;9336:4;9333:1;9326:15;9360:4;9357:1;9350:15;9376:127;9437:10;9432:3;9428:20;9425:1;9418:31;9468:4;9465:1;9458:15;9492:4;9489:1;9482:15;9508:127;9569:10;9564:3;9560:20;9557:1;9550:31;9600:4;9597:1;9590:15;9624:4;9621:1;9614:15;9640:131;-1:-1:-1;;;;;9715:31:1;;9705:42;;9695:2;;9761:1;9758;9751:12;9695:2;9685:86;:::o

Swarm Source

ipfs://2917cd3f5a591a57d448cc6d3fcf34059fa861f3547a324b89e05e4f35e0b795

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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