Contract 0xc21e5e72Ffc223f02fC410aAedE3084a63963932 1

Contract Overview

Balance:
0 Ether
Txn Hash
Method
Block
From
To
Value
0xddb662e0fc349490434d4d5a4bb5e9a9b64ced5043f194eb138c14cbe5d804540x60c0604096703222021-11-19 16:05:07315 days 7 hrs ago0x2a61d3ba5030ef471c74f612962c7367eca3a62d IN  Create: RemoveRewardProgram0 Ether0.000384391.00000001
[ Download CSV Export 
Latest 14 internal transactions
Parent Txn Hash Block From To Value
0xbf78838e08c442905748687f2b2977ae2298d78d1ede42775f1666469c591222100059922022-01-17 9:19:13256 days 14 hrs ago 0xc21e5e72ffc223f02fc410aaede3084a63963932 0x648c8be548f43eca4e482c0801ebccccfb9449310 Ether
0xbf78838e08c442905748687f2b2977ae2298d78d1ede42775f1666469c591222100059922022-01-17 9:19:13256 days 14 hrs ago 0x661090cb830757b2d0cd53c49bf0d17a28992e5d 0xc21e5e72ffc223f02fc410aaede3084a639639320 Ether
0x74a4f73ff001785d09d32a150c4fb52e80cb956b35d8e92c6d9f02ed404c816799781162022-01-12 10:49:57261 days 12 hrs ago 0xc21e5e72ffc223f02fc410aaede3084a63963932 0x648c8be548f43eca4e482c0801ebccccfb9449310 Ether
0x74a4f73ff001785d09d32a150c4fb52e80cb956b35d8e92c6d9f02ed404c816799781162022-01-12 10:49:57261 days 12 hrs ago 0x661090cb830757b2d0cd53c49bf0d17a28992e5d 0xc21e5e72ffc223f02fc410aaede3084a639639320 Ether
0xa248c096bd8a34237fa0d6312b4e6adc653b065d918ce252244a2458a5f8c2d498924412021-12-28 8:53:22276 days 14 hrs ago 0xc21e5e72ffc223f02fc410aaede3084a63963932 0x648c8be548f43eca4e482c0801ebccccfb9449310 Ether
0xa248c096bd8a34237fa0d6312b4e6adc653b065d918ce252244a2458a5f8c2d498924412021-12-28 8:53:22276 days 14 hrs ago 0x661090cb830757b2d0cd53c49bf0d17a28992e5d 0xc21e5e72ffc223f02fc410aaede3084a639639320 Ether
0xb1fa3393d74a448cbd20952e53d7ee2b55ce8cb43c1629dfae50117541fb0b8c97490662021-12-03 8:18:57301 days 15 hrs ago 0xc21e5e72ffc223f02fc410aaede3084a63963932 0x648c8be548f43eca4e482c0801ebccccfb9449310 Ether
0xb1fa3393d74a448cbd20952e53d7ee2b55ce8cb43c1629dfae50117541fb0b8c97490662021-12-03 8:18:57301 days 15 hrs ago 0x661090cb830757b2d0cd53c49bf0d17a28992e5d 0xc21e5e72ffc223f02fc410aaede3084a639639320 Ether
0x13428812e9e7a1cb90317d8d117cda4f3060631dcc2b32696cfd6e315d49277e97091312021-11-26 9:51:37308 days 13 hrs ago 0xc21e5e72ffc223f02fc410aaede3084a63963932 0x648c8be548f43eca4e482c0801ebccccfb9449310 Ether
0x13428812e9e7a1cb90317d8d117cda4f3060631dcc2b32696cfd6e315d49277e97091312021-11-26 9:51:37308 days 13 hrs ago 0x661090cb830757b2d0cd53c49bf0d17a28992e5d 0xc21e5e72ffc223f02fc410aaede3084a639639320 Ether
0x0247dd575eb17e3af5b2b385f18ffdf20eb2521d63bd124c78a31aefb5d8e29197089102021-11-26 8:56:22308 days 14 hrs ago 0xc21e5e72ffc223f02fc410aaede3084a63963932 0x648c8be548f43eca4e482c0801ebccccfb9449310 Ether
0x0247dd575eb17e3af5b2b385f18ffdf20eb2521d63bd124c78a31aefb5d8e29197089102021-11-26 8:56:22308 days 14 hrs ago 0x661090cb830757b2d0cd53c49bf0d17a28992e5d 0xc21e5e72ffc223f02fc410aaede3084a639639320 Ether
0xfda70026a9be789e0397b16ac13fddecc3d79edbe7164285908d9dda2591c1eb97087862021-11-26 8:25:22308 days 15 hrs ago 0xc21e5e72ffc223f02fc410aaede3084a63963932 0x648c8be548f43eca4e482c0801ebccccfb9449310 Ether
0xfda70026a9be789e0397b16ac13fddecc3d79edbe7164285908d9dda2591c1eb97087862021-11-26 8:25:22308 days 15 hrs ago 0x661090cb830757b2d0cd53c49bf0d17a28992e5d 0xc21e5e72ffc223f02fc410aaede3084a639639320 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RemoveRewardProgram

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-11-19
*/

// 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/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/RemoveRewardProgram.sol

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

pragma solidity ^0.8.4;





/// @author psirex
/// @notice Creates EVMScript to remove reward program from RewardProgramsRegistry
contract RemoveRewardProgram is TrustedCaller, IEVMScriptFactory {
    // -------------
    // ERRORS
    // -------------
    string private constant ERROR_REWARD_PROGRAM_NOT_FOUND = "REWARD_PROGRAM_NOT_FOUND";

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

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

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

    constructor(address _trustedCaller, address _rewardProgramsRegistry)
        TrustedCaller(_trustedCaller)
    {
        rewardProgramsRegistry = RewardProgramsRegistry(_rewardProgramsRegistry);
    }

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

    /// @notice Creates EVMScript to remove reward program from RewardProgramsRegistry
    /// @param _creator Address who creates EVMScript
    /// @param _evmScriptCallData Encoded tuple: (address _rewardProgram)
    function createEVMScript(address _creator, bytes memory _evmScriptCallData)
        external
        view
        override
        onlyTrustedCaller(_creator)
        returns (bytes memory)
    {
        require(
            rewardProgramsRegistry.isRewardProgram(_decodeEVMScriptCallData(_evmScriptCallData)),
            ERROR_REWARD_PROGRAM_NOT_FOUND
        );
        return
            EVMScriptCreator.createEVMScript(
                address(rewardProgramsRegistry),
                rewardProgramsRegistry.removeRewardProgram.selector,
                _evmScriptCallData
            );
    }

    /// @notice Decodes call data used by createEVMScript method
    /// @param _evmScriptCallData Encoded tuple: (address _rewardProgram)
    /// @return _rewardProgram Address of reward program to remove
    function decodeEVMScriptCallData(bytes memory _evmScriptCallData)
        external
        pure
        returns (address _rewardProgram)
    {
        return _decodeEVMScriptCallData(_evmScriptCallData);
    }

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

    function _decodeEVMScriptCallData(bytes memory _evmScriptCallData)
        private
        pure
        returns (address)
    {
        return abi.decode(_evmScriptCallData, (address));
    }
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_trustedCaller","type":"address"},{"internalType":"address","name":"_rewardProgramsRegistry","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":"_rewardProgram","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"rewardProgramsRegistry","outputs":[{"internalType":"contract RewardProgramsRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trustedCaller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60c060405234801561001057600080fd5b5060405161077e38038061077e83398101604081905261002f916100d2565b60408051808201909152601e81527f545255535445445f43414c4c45525f49535f5a45524f5f414444524553530000602082015282906001600160a01b0382166100955760405162461bcd60e51b815260040161008c9190610105565b60405180910390fd5b506001600160601b0319606091821b811660805291901b1660a0525061015a565b80516001600160a01b03811681146100cd57600080fd5b919050565b600080604083850312156100e557600080fd5b6100ee836100b6565b91506100fc602084016100b6565b90509250929050565b600060208083528351808285015260005b8181101561013257858101830151858201604001528201610116565b81811115610144576000604083870101525b50601f01601f1916929092016040019392505050565b60805160601c60a05160601c6105e661019860003960008181609a0152818161018e01526102950152600081816056015261010501526105e66000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063268f0760146100515780633f052ae914610095578063ecf7c690146100bc578063fea21c9c146100cf575b600080fd5b6100787f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100787f000000000000000000000000000000000000000000000000000000000000000081565b6100786100ca366004610447565b6100ef565b6100e26100dd3660046103d5565b610100565b60405161008c9190610509565b60006100fa826102ca565b92915050565b6060827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316146040518060400160405280601381526020017221a0a62622a92fa4a9afa327a92124a22222a760691b8152509061018b5760405162461bcd60e51b81526004016101829190610509565b60405180910390fd5b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639525581c6101c4856102ca565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b15801561020357600080fd5b505afa158015610217573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023b9190610425565b6040518060400160405280601881526020017f5245574152445f50524f4752414d5f4e4f545f464f554e4400000000000000008152509061028f5760405162461bcd60e51b81526004016101829190610509565b506102c27f0000000000000000000000000000000000000000000000000000000000000000634a2919f160e11b856102e0565b949350505050565b6000818060200190518101906100fa91906103b1565b6060600160e01b84835160046102f6919061051c565b858560405160200161030c9594939291906104a8565b60405160208183030381529060405290509392505050565b600082601f83011261033557600080fd5b813567ffffffffffffffff8082111561035057610350610582565b604051601f8301601f19908116603f0116810190828211818310171561037857610378610582565b8160405283815286602085880101111561039157600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000602082840312156103c357600080fd5b81516103ce81610598565b9392505050565b600080604083850312156103e857600080fd5b82356103f381610598565b9150602083013567ffffffffffffffff81111561040f57600080fd5b61041b85828601610324565b9150509250929050565b60006020828403121561043757600080fd5b815180151581146103ce57600080fd5b60006020828403121561045957600080fd5b813567ffffffffffffffff81111561047057600080fd5b6102c284828501610324565b60008151808452610494816020860160208601610552565b601f01601f19169290920160200192915050565b6001600160e01b03198681168252606086901b6bffffffffffffffffffffffff1916600483015260e085901b811660188301528316601c82015281516000906104f8816020808601908701610552565b919091016020019695505050505050565b6020815260006103ce602083018461047c565b600063ffffffff80831681851680830382111561054957634e487b7160e01b600052601160045260246000fd5b01949350505050565b60005b8381101561056d578181015183820152602001610555565b8381111561057c576000848401525b50505050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146105ad57600080fd5b5056fea26469706673582212207d4c13803327b1b5adceaee04bb6ed5541a922604c75ed548f7780c698bd6fa464736f6c63430008060033000000000000000000000000b9b953bb58411d7932d76a2493e309c88f9f2e13000000000000000000000000648c8be548f43eca4e482c0801ebccccfb944931

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

000000000000000000000000b9b953bb58411d7932d76a2493e309c88f9f2e13000000000000000000000000648c8be548f43eca4e482c0801ebccccfb944931

-----Decoded View---------------
Arg [0] : _trustedCaller (address): 0xB9b953Bb58411D7932D76A2493e309c88F9f2e13
Arg [1] : _rewardProgramsRegistry (address): 0x648C8Be548F43eca4e482C0801Ebccccfb944931

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000b9b953bb58411d7932d76a2493e309c88f9f2e13
Arg [1] : 000000000000000000000000648c8be548f43eca4e482c0801ebccccfb944931


Deployed ByteCode Sourcemap

24554:2313:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;587:38;;;;;;;;-1:-1:-1;;;;;3156:32:1;;;3138:51;;3126:2;3111:18;587:38:0;;;;;;;;24893:62;;;;;26364:215;;;;;;:::i;:::-;;:::i;25531:616::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;26364:215::-;26480:22;26527:44;26552:18;26527:24;:44::i;:::-;26520:51;26364:215;-1:-1:-1;;26364:215:0:o;25531:616::-;25712:12;25684: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;:::-;;;;;;;;;;25764:22:::1;-1:-1:-1::0;;;;;25764:38:0::1;;25803:44;25828:18;25803:24;:44::i;:::-;25764:84;::::0;-1:-1:-1;;;;;;25764:84:0::1;::::0;;;;;;-1:-1:-1;;;;;3156:32:1;;;25764:84:0::1;::::0;::::1;3138:51:1::0;3111:18;;25764:84:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;25863:30;;;;;;;;;;;;;;;;::::0;25742:162:::1;;;;;-1:-1:-1::0;;;25742:162:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;25935:204:0::1;25994:22;-1:-1:-1::0;;;26106:18:0;25935:32:::1;:204::i;:::-;25915:224:::0;25531:616;-1:-1:-1;;;;25531:616:0:o;26667:197::-;26783:7;26826:18;26815:41;;;;;;;;;;;;:::i;21059:409::-;21205:22;-1:-1:-1;;;21321:3:0;21350:18;:25;21379:1;21343:37;;;;:::i;:::-;21399:9;21427:18;21260:200;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;21240:220;;21059:409;;;;;:::o;14:718:1:-;56:5;109:3;102:4;94:6;90:17;86:27;76:2;;127:1;124;117:12;76:2;163:6;150:20;189:18;226:2;222;219:10;216:2;;;232:18;;:::i;:::-;307:2;301:9;275:2;361:13;;-1:-1:-1;;357:22:1;;;381:2;353:31;349:40;337:53;;;405:18;;;425:22;;;402:46;399:2;;;451:18;;:::i;:::-;491:10;487:2;480:22;526:2;518:6;511:18;572:3;565:4;560:2;552:6;548:15;544:26;541:35;538:2;;;589:1;586;579:12;538:2;653;646:4;638:6;634:17;627:4;619:6;615:17;602:54;700:1;693:4;688:2;680:6;676:15;672:26;665:37;720:6;711:15;;;;;;66:666;;;;:::o;737:259::-;815:6;868:2;856:9;847:7;843:23;839:32;836:2;;;884:1;881;874:12;836:2;916:9;910:16;935:31;960:5;935:31;:::i;:::-;985:5;826:170;-1:-1:-1;;;826:170:1:o;1001:455::-;1078:6;1086;1139:2;1127:9;1118:7;1114:23;1110:32;1107:2;;;1155:1;1152;1145:12;1107:2;1194:9;1181:23;1213:31;1238:5;1213:31;:::i;:::-;1263:5;-1:-1:-1;1319:2:1;1304:18;;1291:32;1346:18;1335:30;;1332:2;;;1378:1;1375;1368:12;1332:2;1401:49;1442:7;1433:6;1422:9;1418:22;1401:49;:::i;:::-;1391:59;;;1097:359;;;;;:::o;1461:277::-;1528:6;1581:2;1569:9;1560:7;1556:23;1552:32;1549:2;;;1597:1;1594;1587:12;1549:2;1629:9;1623:16;1682:5;1675:13;1668:21;1661:5;1658:32;1648:2;;1704:1;1701;1694:12;1743:320;1811:6;1864:2;1852:9;1843:7;1839:23;1835:32;1832:2;;;1880:1;1877;1870:12;1832:2;1920:9;1907:23;1953:18;1945:6;1942:30;1939:2;;;1985:1;1982;1975:12;1939:2;2008:49;2049:7;2040:6;2029:9;2025:22;2008:49;:::i;2068:257::-;2109:3;2147:5;2141:12;2174:6;2169:3;2162:19;2190:63;2246:6;2239:4;2234:3;2230:14;2223:4;2216:5;2212:16;2190:63;:::i;:::-;2307:2;2286:15;-1:-1:-1;;2282:29:1;2273:39;;;;2314:4;2269:50;;2117:208;-1:-1:-1;;2117:208:1:o;2330:657::-;-1:-1:-1;;;;;;2634:15:1;;;2622:28;;2687:2;2683:15;;;-1:-1:-1;;2679:53:1;2675:1;2666:11;;2659:74;2597:3;2767:16;;;2763:25;;2758:2;2749:12;;2742:47;2819:15;;2814:2;2805:12;;2798:37;2858:13;;2565:3;;2880:60;2858:13;2928:2;2919:12;;;;2902:15;;2880:60;:::i;:::-;2960:16;;;;2978:2;2956:25;;2573:414;-1:-1:-1;;;;;;2573:414:1:o;3200:217::-;3347:2;3336:9;3329:21;3310:4;3367:44;3407:2;3396:9;3392:18;3384:6;3367:44;:::i;3884:325::-;3923:3;3951:10;3988:2;3985:1;3981:10;4018:2;4015:1;4011:10;4049:3;4045:2;4041:12;4036:3;4033:21;4030:2;;;4096:10;4091:3;4087:20;4084:1;4077:31;4131:4;4128:1;4121:15;4159:4;4156:1;4149:15;4030:2;4190:13;;3931:278;-1:-1:-1;;;;3931:278:1:o;4214:258::-;4286:1;4296:113;4310:6;4307:1;4304:13;4296:113;;;4386:11;;;4380:18;4367:11;;;4360:39;4332:2;4325:10;4296:113;;;4427:6;4424:1;4421:13;4418:2;;;4462:1;4453:6;4448:3;4444:16;4437:27;4418:2;;4267:205;;;:::o;4477:127::-;4538:10;4533:3;4529:20;4526:1;4519:31;4569:4;4566:1;4559:15;4593:4;4590:1;4583:15;4609:131;-1:-1:-1;;;;;4684:31:1;;4674:42;;4664:2;;4730:1;4727;4720:12;4664:2;4654:86;:::o

Swarm Source

ipfs://7d4c13803327b1b5adceaee04bb6ed5541a922604c75ed548f7780c698bd6fa4
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading

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