ETH Price: $3,312.73 (+5.84%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Sweep Rewards239710742025-12-08 22:31:3528 hrs ago1765233095IN
0xe3B17b45...937129894
0 ETH0.000319180.29198141
Subscribe Valida...239372682025-12-04 3:28:235 days ago1764818903IN
0xe3B17b45...937129894
0 ETH0.000024220.52245948
Set Reward Recip...239372592025-12-04 3:25:475 days ago1764818747IN
0xe3B17b45...937129894
0 ETH0.000024080.52947906
Sweep Rewards238934772025-11-28 0:00:5912 days ago1764288059IN
0xe3B17b45...937129894
0 ETH0.000043190.04005936
Transfer238934232025-11-27 23:49:5912 days ago1764287399IN
0xe3B17b45...937129894
0.00890511 ETH0.000000820.03688712
Sweep Rewards238835252025-11-26 14:30:5913 days ago1764167459IN
0xe3B17b45...937129894
0 ETH0.000058160.05504415
Transfer238833542025-11-26 13:56:1113 days ago1764165371IN
0xe3B17b45...937129894
0.04583741 ETH0.000001170.0520637
Sweep Rewards238809292025-11-26 5:45:5913 days ago1764135959IN
0xe3B17b45...937129894
0 ETH0.000068210.06427081
Set Reward Recip...238793122025-11-26 0:18:4714 days ago1764116327IN
0xe3B17b45...937129894
0 ETH0.000004540.1
Sweep Rewards238748082025-11-25 9:03:5914 days ago1764061439IN
0xe3B17b45...937129894
0 ETH0.000174080.16407896
Subscribe Valida...238704792025-11-24 18:25:4715 days ago1764008747IN
0xe3B17b45...937129894
0 ETH0.00016730.62584761
Sweep Rewards238384862025-11-20 6:31:1119 days ago1763620271IN
0xe3B17b45...937129894
0 ETH0.000789450.72400765
Transfer238383772025-11-20 6:08:5919 days ago1763618939IN
0xe3B17b45...937129894
0.01163014 ETH0.000015190.67593732
Sweep Rewards238089982025-11-16 3:15:5923 days ago1763262959IN
0xe3B17b45...937129894
0 ETH0.000070350.06464982
Transfer238089772025-11-16 3:11:4723 days ago1763262707IN
0xe3B17b45...937129894
0.00488781 ETH0.000001580.07030719
Sweep Rewards237958062025-11-14 7:02:1125 days ago1763103731IN
0xe3B17b45...937129894
0 ETH0.001694471.56061057
Transfer237958012025-11-14 7:01:1125 days ago1763103671IN
0xe3B17b45...937129894
0.03081638 ETH0.000033311.48237857
Sweep Rewards237718512025-11-10 22:31:3529 days ago1762813895IN
0xe3B17b45...937129894
0 ETH0.000170090.157684
Transfer237718132025-11-10 22:23:5929 days ago1762813439IN
0xe3B17b45...937129894
0.02680455 ETH0.000003680.16380235
Sweep Rewards237644782025-11-09 21:46:3530 days ago1762724795IN
0xe3B17b45...937129894
0 ETH0.000079840.07284511
Transfer237644522025-11-09 21:41:2330 days ago1762724483IN
0xe3B17b45...937129894
0.01085866 ETH0.000001460.06509719
Subscribe Valida...237611002025-11-09 10:26:5930 days ago1762684019IN
0xe3B17b45...937129894
0 ETH0.000081881.76621279
Sweep Rewards237414602025-11-06 16:34:2333 days ago1762446863IN
0xe3B17b45...937129894
0 ETH0.003795493.50092424
Transfer237406352025-11-06 13:47:4733 days ago1762436867IN
0xe3B17b45...937129894
0.01545161 ETH0.000084633.76566104
Sweep Rewards237403302025-11-06 12:46:2333 days ago1762433183IN
0xe3B17b45...937129894
0 ETH0.001612281.48719444
View all transactions

Latest 21 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Deposit Funds239710742025-12-08 22:31:3528 hrs ago1765233095
0xe3B17b45...937129894
0.0089504 ETH
Transfer239710152025-12-08 22:19:4728 hrs ago1765232387
0xe3B17b45...937129894
0.0089504 ETH
Deposit Funds238934772025-11-28 0:00:5912 days ago1764288059
0xe3B17b45...937129894
0.00890511 ETH
Deposit Funds238835252025-11-26 14:30:5913 days ago1764167459
0xe3B17b45...937129894
0.04583741 ETH
Deposit Funds238809292025-11-26 5:45:5913 days ago1764135959
0xe3B17b45...937129894
0.0025368 ETH
Deposit Funds238748082025-11-25 9:03:5914 days ago1764061439
0xe3B17b45...937129894
0.00185248 ETH
Deposit Funds238384862025-11-20 6:31:1119 days ago1763620271
0xe3B17b45...937129894
0.01163014 ETH
Deposit Funds238089982025-11-16 3:15:5923 days ago1763262959
0xe3B17b45...937129894
0.00488781 ETH
Deposit Funds237958062025-11-14 7:02:1125 days ago1763103731
0xe3B17b45...937129894
0.03081638 ETH
Deposit Funds237718512025-11-10 22:31:3529 days ago1762813895
0xe3B17b45...937129894
0.02680455 ETH
Deposit Funds237644782025-11-09 21:46:3530 days ago1762724795
0xe3B17b45...937129894
0.01085866 ETH
Deposit Funds237414602025-11-06 16:34:2333 days ago1762446863
0xe3B17b45...937129894
0.01545161 ETH
Deposit Funds237403302025-11-06 12:46:2333 days ago1762433183
0xe3B17b45...937129894
0.01183646 ETH
Deposit Funds237288722025-11-04 22:16:2335 days ago1762294583
0xe3B17b45...937129894
0.00452774 ETH
Deposit Funds237120262025-11-02 13:45:5937 days ago1762091159
0xe3B17b45...937129894
0.01289826 ETH
Deposit Funds237077812025-11-01 23:32:2338 days ago1762039943
0xe3B17b45...937129894
0.008508 ETH
Deposit Funds236931882025-10-30 22:31:2340 days ago1761863483
0xe3B17b45...937129894
0.00621375 ETH
Deposit Funds236922232025-10-30 19:16:2340 days ago1761851783
0xe3B17b45...937129894
0.00691186 ETH
Deposit Funds236710422025-10-27 20:04:1143 days ago1761595451
0xe3B17b45...937129894
0.01370925 ETH
Deposit Funds234888502025-10-02 8:15:5968 days ago1759392959
0xe3B17b45...937129894
0.01 ETH
0x60806040234816542025-10-01 8:05:4769 days ago1759305947  Contract Creation0 ETH
Loading...
Loading
Cross-Chain Transactions
Produced Blocks

 Latest 3 blocks produced

Block Transaction Difficulty Gas Used Reward
238809122025-11-26 5:42:3513 days ago1764135755960.00 TH47,172,062 (78.62%)
0.002536805248662714 ETH
238743852025-11-25 7:38:3514 days ago17640563151090.00 TH27,969,153 (58.13%)
0.001852488829965323 ETH
237285842025-11-04 21:17:5935 days ago17622910791560.00 TH8,346,026 (18.58%)
0.00452774182389697 ETH

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SebaPool

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 10000 runs

Other Settings:
cancun EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
import { ISebaPool } from "src/interfaces/ISebaPool.sol";
import { IYieldManager } from "src/interfaces/IYieldManager.sol";
import { IPYBSeba } from "src/interfaces/IPYBSeba.sol";

/**
 * @title SebaPool
 * @notice Implements the SebaPool functionality for validator subscriptions, graduation,
 * and reward distribution.
 * @dev Inherits from AccessControl to manage roles. See {ISebaPool} for external interface.
 */
contract SebaPool is AccessControl, ISebaPool {
    /*//////////////////////////////////////////////////////////////
                              CONSTANTS
    //////////////////////////////////////////////////////////////*/

    /// @notice The duration of the graduation period in blocks (6 months).
    uint256 public constant GRADUATION_DURATION_IN_BLOCKS = 1314872;

    /// @notice Role identifier for administrative functions.
    bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
    /// @notice Role identifier for automator functions.
    bytes32 public constant AUTOMATOR_ROLE = keccak256("AUTOMATOR_ROLE");

    /*//////////////////////////////////////////////////////////////
                              STATE VARIABLES
    //////////////////////////////////////////////////////////////*/

    /// @inheritdoc ISebaPool
    IPYBSeba public sebaVault;
    /// @inheritdoc ISebaPool
    IYieldManager public yieldManager;

    /// @notice Mapping from a withdrawal address to its delegated reward recipient.
    mapping(address => address) public override rewardRecipient;
    /// @notice Mapping from a validator ID to the block number when it was registered.
    mapping(uint256 => uint256) public override validatorRegistrationBlock;
    /// @notice Mapping that indicates whether a validator has already graduated.
    mapping(uint256 => bool) public override validatorIsGraduated;

    /*//////////////////////////////////////////////////////////////
                              CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    /**
     * @notice Initializes the BoostPool contract.
     * @dev Sets the initial roles and immutable contract references.
     * @param _admin The address to be granted the ADMIN_ROLE.
     * @param _automator The address to be granted the AUTOMATOR_ROLE.
     */
    constructor(address _admin, address _automator) {
        if (_admin == address(0)) revert InvalidAddress();
        if (_automator == address(0)) revert InvalidAddress();

        _grantRole(ADMIN_ROLE, _admin);
        _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);
        _grantRole(AUTOMATOR_ROLE, _automator);
        _setRoleAdmin(AUTOMATOR_ROLE, ADMIN_ROLE);
    }

    /*//////////////////////////////////////////////////////////////
                              FALLBACK
    //////////////////////////////////////////////////////////////*/

    /**
     * @notice Be able to receive ether donations and MEV rewards
     **/
    fallback() external payable {
        emit EtherReceived(msg.sender, msg.value);
    }

    /*//////////////////////////////////////////////////////////////
                              PUBLIC FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @inheritdoc ISebaPool
    function subscribeValidator(uint64 _validatorId) external override {
        if (validatorRegistrationBlock[_validatorId] != 0) revert ValidatorAlreadySubscribed(_validatorId);

        validatorRegistrationBlock[_validatorId] = block.number;

        emit SubscribeValidator(msg.sender, _validatorId);
    }

    /// @inheritdoc ISebaPool
    function subscribeValidators(uint64[] calldata _validatorIdArray) external override {
        for (uint256 i = 0; i < _validatorIdArray.length; ) {
            if (validatorRegistrationBlock[_validatorIdArray[i]] != 0)
                revert ValidatorAlreadySubscribed(_validatorIdArray[i]);

            validatorRegistrationBlock[_validatorIdArray[i]] = block.number;

            emit SubscribeValidator(msg.sender, _validatorIdArray[i]);

            unchecked {
                i += 1;
            }
        }
    }

    /// @inheritdoc ISebaPool
    function setRewardRecipient(address _rewardAddress) external override {
        rewardRecipient[msg.sender] = _rewardAddress;
        emit SetRewardRecipient(msg.sender, _rewardAddress);
    }

    /// @inheritdoc ISebaPool
    function sweepRewards() external override {
        uint256 funds = address(this).balance;
        if (funds > 0) {
            yieldManager.depositFunds{ value: funds }();
            emit RewardsSwept(funds, address(yieldManager));
        }
    }

    /// @inheritdoc ISebaPool
    function graduateValidator(
        uint256 _validatorId,
        address _withdrawalAddress,
        uint256 _attestationPoints
    ) external override onlyRole(AUTOMATOR_ROLE) {
        if (validatorRegistrationBlock[_validatorId] == 0) revert ValidatorNotSubscribed(_validatorId);
        if (validatorIsGraduated[_validatorId]) revert ValidatorAlreadyGraduated(_validatorId);
        if (block.number < validatorRegistrationBlock[_validatorId] + GRADUATION_DURATION_IN_BLOCKS)
            revert GraduationPeriodNotOver(_validatorId);

        if (rewardRecipient[_withdrawalAddress] != address(0)) {
            _withdrawalAddress = rewardRecipient[_withdrawalAddress];
        }
        validatorIsGraduated[_validatorId] = true;
        sebaVault.distributeShares(_withdrawalAddress, _attestationPoints);
        emit ValidatorGraduated(_validatorId, _withdrawalAddress, _attestationPoints);
    }

    /// @inheritdoc ISebaPool
    function setYieldManager(address _yieldManager) external override onlyRole(ADMIN_ROLE) {
        if (_yieldManager == address(0)) revert InvalidAddress();
        yieldManager = IYieldManager(_yieldManager);
        emit YieldManagerSet(_yieldManager);
    }

    function setSebaVault(address _sebaVault) external override onlyRole(ADMIN_ROLE) {
        if (_sebaVault == address(0)) revert InvalidAddress();
        sebaVault = IPYBSeba(_sebaVault);
        emit SebaVaultSet(_sebaVault);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)

pragma solidity ^0.8.20;

import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";

/**
 * @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:
 *
 * ```solidity
 * 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}:
 *
 * ```solidity
 * 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. We recommend using {AccessControlDefaultAdminRules}
 * to enforce additional security measures for this role.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address account => bool) hasRole;
        bytes32 adminRole;
    }

    mapping(bytes32 role => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with an {AccessControlUnauthorizedAccount} error including the required role.
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

    /**
     * @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 virtual returns (bool) {
        return _roles[role].hasRole[account];
    }

    /**
     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
     * is missing `role`.
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert AccessControlUnauthorizedAccount(account, role);
        }
    }

    /**
     * @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 virtual 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.
     *
     * May emit a {RoleGranted} event.
     */
    function grantRole(bytes32 role, address account) public virtual 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.
     *
     * May emit a {RoleRevoked} event.
     */
    function revokeRole(bytes32 role, address account) public virtual 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 revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `callerConfirmation`.
     *
     * May emit a {RoleRevoked} event.
     */
    function renounceRole(bytes32 role, address callerConfirmation) public virtual {
        if (callerConfirmation != _msgSender()) {
            revert AccessControlBadConfirmation();
        }

        _revokeRole(role, callerConfirmation);
    }

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

    /**
     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleGranted} event.
     */
    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
        if (!hasRole(role, account)) {
            _roles[role].hasRole[account] = true;
            emit RoleGranted(role, account, _msgSender());
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
        if (hasRole(role, account)) {
            _roles[role].hasRole[account] = false;
            emit RoleRevoked(role, account, _msgSender());
            return true;
        } else {
            return false;
        }
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import { IPoap } from "src/interfaces/IPoap.sol";
import { IYieldManager } from "src/interfaces/IYieldManager.sol";
import { IPYBSeba } from "src/interfaces/IPYBSeba.sol";

/**
 * @title IBoostPool
 * @notice Interface for the BoostPool contract.
 * @dev The BoostPool manages validator subscriptions, graduation, and reward distribution.
 */
interface ISebaPool {
    /*//////////////////////////////////////////////////////////////
                              ERRORS
    //////////////////////////////////////////////////////////////*/

    /// @notice Thrown when a staker does not own the given POAP or when the POAP event does not match the required stakers union.
    error NonEligibleStaker(address staker, uint256 poapID);
    /// @notice Thrown when an address parameter is the zero address.
    error InvalidAddress();
    /// @notice Thrown when a validator is already subscribed to the pool.
    error ValidatorAlreadySubscribed(uint256 validatorId);
    /// @notice Thrown when a validator has already graduated.
    error ValidatorAlreadyGraduated(uint256 validatorId);
    /// @notice Thrown when a validator is not subscribed.
    error ValidatorNotSubscribed(uint256 validatorId);
    /// @notice Thrown when the graduation period for a validator has not yet passed.
    error GraduationPeriodNotOver(uint256 validatorId);

    /*//////////////////////////////////////////////////////////////
                              EVENTS
    //////////////////////////////////////////////////////////////*/

    /// @notice Emitted when the BoostPool contract receives Ether (donations or MEV rewards).
    /// @param sender The address sending Ether.
    /// @param donationAmount The amount of Ether received.
    event EtherReceived(address indexed sender, uint256 donationAmount);

    /// @notice Emitted when a validator is subscribed to the pool.
    /// @param staker The address of the staker who subscribed.
    /// @param validatorId The ID of the validator that was subscribed.
    event SubscribeValidator(address indexed staker, uint256 indexed validatorId);

    /// @notice Emitted when a withdrawal address sets or updates its reward recipient.
    /// @param withdrawalAddress The address that sets its reward recipient.
    /// @param poolRecipient The address designated as the reward recipient.
    event SetRewardRecipient(address indexed withdrawalAddress, address indexed poolRecipient);

    /// @notice Emitted when rewards (Ether) are swept into the yield manager.
    /// @param amount The amount of Ether swept.
    /// @param yieldManager The address of the yield manager that receives the funds.
    event RewardsSwept(uint256 amount, address indexed yieldManager);

    /// @notice Emitted when the yield manager address is updated.
    /// @param yieldManager The new yield manager address.
    event YieldManagerSet(address indexed yieldManager);

    /// @notice Emitted when a validator graduates, receiving reward shares.
    /// @param validatorId The ID of the validator that graduated.
    /// @param withdrawalAddress The address that received the graduation rewards.
    /// @param attestationPoints The number of attestation points used to calculate the reward.
    event ValidatorGraduated(uint256 indexed validatorId, address indexed withdrawalAddress, uint256 attestationPoints);

    /// @notice Emitted when the Seba Vault contract address is updated.
    /// @param _sebaVault The new Seba Vault contract address.
    event SebaVaultSet(address _sebaVault);

    /*//////////////////////////////////////////////////////////////
                         PUBLIC CONSTANTS & VARIABLES
    //////////////////////////////////////////////////////////////*/

    /// @notice The duration of the graduation period in blocks (e.g., 180 days).
    function GRADUATION_DURATION_IN_BLOCKS() external view returns (uint256);

    /// @notice The role identifier for administrative functions.
    function ADMIN_ROLE() external view returns (bytes32);

    /// @notice The role identifier for automator functions.
    function AUTOMATOR_ROLE() external view returns (bytes32);

    /// @notice The Seba Vault contract instance.
    function sebaVault() external view returns (IPYBSeba);

    /// @notice The yield manager contract instance.
    function yieldManager() external view returns (IYieldManager);

    /// @notice Mapping that returns the reward recipient for a given withdrawal address.
    function rewardRecipient(address) external view returns (address);

    /// @notice Mapping that returns the block number when a validator was registered.
    function validatorRegistrationBlock(uint256) external view returns (uint256);

    /// @notice Mapping that indicates whether a validator has graduated.
    function validatorIsGraduated(uint256) external view returns (bool);

    /*//////////////////////////////////////////////////////////////
                              FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /**
     * @notice Subscribes a validator to the BoostPool.
     * @dev A staker must own the specified POAP and the POAP must be from the stakers union.
     * @param _validatorId The ID of the validator to subscribe.
     */
    function subscribeValidator(uint64 _validatorId) external;

    /**
     * @notice Subscribes multiple validators to the BoostPool.
     * @param _validatorIdArray An array of validator IDs to subscribe.
     */
    function subscribeValidators(uint64[] calldata _validatorIdArray) external;

    /**
     * @notice Sets the reward recipient for the caller's withdrawal address.
     * @param _rewardAddress The address to be designated as the reward recipient.
     */
    function setRewardRecipient(address _rewardAddress) external;

    /**
     * @notice Sweeps any Ether held by the BoostPool into the yield manager.
     * @dev This function deposits the entire Ether balance of the contract into the yield manager.
     */
    function sweepRewards() external;

    /**
     * @notice Graduates a validator from the BoostPool, awarding reward shares.
     * @dev Graduation can only occur after the required graduation period has elapsed.
     * If a reward delegation is set for the withdrawal address, rewards are sent to that delegated address.
     * @param _validatorId The ID of the validator to graduate.
     * @param _withdrawalAddress The address to receive the graduation rewards.
     * @param _attestationPoints The total attestation points accumulated by the validator.
     */
    function graduateValidator(uint256 _validatorId, address _withdrawalAddress, uint256 _attestationPoints) external;

    /**
     * @notice Updates the yield manager contract address.
     * @param _yieldManager The new yield manager contract address.
     */
    function setYieldManager(address _yieldManager) external;

    function setSebaVault(address _sebaVault) external;
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IEthToBoldRouter } from "src/interfaces/IEthToBoldRouter.sol";
import { ISBOLD } from "src/vendor/liquity/ISBOLD.sol";
import { IPYBSeba } from "src/interfaces/IPYBSeba.sol";
import { IYieldVault } from "src/interfaces/IYieldVault.sol";

/**
 * @title IYieldManager
 * @notice Interface for the Seba Yield-Manager that
 *         - handles BoostPool funding (50 / 50 split),
 *         - accepts time-locked user deposits,
 *         - manages ETH→BOLD→sBOLD conversion and SebaVault top-ups,
 *         - claims and routes strategy yield,
 *         - lets admins migrate or pull principal from the active vault.
 */
interface IYieldManager {
    /*//////////////////////////////////////////////////////////////
                               STRUCTS
    //////////////////////////////////////////////////////////////*/

    /// @notice Configuration for one user deposit that is locked for
    ///         `USER_LOCK_SECS` seconds after the block timestamp.
    /// @param depositor        The user who supplied the ETH.
    /// @param vaultAtDeposit   Strategy vault that currently holds the funds.
    /// @param amount           Principal amount in underlying (ETH value, wei).
    /// @param unlockTime       Timestamp (UTC-seconds) after which withdrawal
    ///                         via {retrieveFunds} is allowed.
    struct Deposit {
        address depositor;
        IYieldVault vaultAtDeposit;
        uint256 amount;
        uint32 unlockTime;
    }

    /*//////////////////////////////////////////////////////////////
                                ERRORS
    //////////////////////////////////////////////////////////////*/

    /// Thrown when an address argument is zero.
    error InvalidAddress();

    /// Thrown when `msg.value == 0` in {depositFunds}.
    error EmptyDeposit();

    /// Thrown when trying to cancel a CowSwap order but no UID is stored.
    error NoActiveRouterIntent();

    /// Thrown if {activateYieldFlow} is called more than once.
    error YieldFlowAlreadyActivated();

    // Value of deposit is zero
    error ZeroDepositValue();

    /// Thrown when a referenced deposit‐ID does not exist.
    error NonExistingDeposit(uint256 id);

    /// Thrown when someone other than the original depositor calls {retrieveFunds}.
    error InvalidDepositor(address depositor);

    /// Thrown when a user tries to withdraw before `unlockTime`.
    error DepositStillLocked(uint256 now_, uint32 unlockTime);

    /// Thrown when an ETH transfer to a user fails.
    error TransferFailed();

    /// Thrown when admin tries to pull protocol principal but none is deployed.
    error NoPrincipalDeployed();

    /// Thrown when the slippage is configured too high
    error SlippageTooHigh();

    /// Thrown when the max fee is configured too high
    error MaxFeeTooHigh();

    /// Thrown when the invalidity is set to 0
    error InvalidValidity();

    /*//////////////////////////////////////////////////////////////
                                EVENTS
    //////////////////////////////////////////////////////////////*/

    /// Emitted after any ETH deposit is processed
    /// (BoostPool or external user).
    /// @param from              Sender of the ETH.
    /// @param amountUnderlying  Amount accounted as *underlying* (ETH value)
    ///                          and forwarded to a strategy vault (if any).
    event DepositReceived(address indexed from, uint256 amountUnderlying);

    /// Emitted when a new ETH→BOLD CowSwap order (intent) is started.
    /// @param uid    56-byte unique identifier returned by Eth-flow.
    /// @param ethIn  Exact ETH amount committed to the order.
    event BoldConversionStarted(bytes32 uid, uint256 ethIn);

    /// Emitted when BOLD is converted to sBOLD and staked into SebaVault.
    /// @param boldIn   BOLD tokens consumed.
    /// @param sBoldOut sBOLD tokens minted & deposited.
    event BoldConversionFinalised(uint256 boldIn, uint256 sBoldOut);

    /// Emitted once when admin switches yield routing to SebaVault.
    event YieldFlowActivated();

    /// Emitted every time yield is handled.
    /// @param ethAmount    Yield size in ETH.
    /// @param toSebaVault  True  = routed to SebaVault via conversion.<br>
    ///                     False = auto-compounded in the current vault.
    event YieldDistributed(uint256 ethAmount, bool toSebaVault);

    /// Emitted when slippage tolerance for CowSwap intents is adjusted.
    event RouterSlippageBpsSet(uint16 previous, uint16 current);

    /// Emitted when max fee tolerance for CowSwap intents is adjusted.
    event MaxFeeBpsSet(uint16 previous, uint16 current);

    /// Emitted when validity window for CowSwap intents is adjusted.
    event RouterValiditySecsSet(uint32 previous, uint32 current);

    /// Emitted after a successful strategy-vault migration.
    event NewYieldVaultSet(address yieldVault);

    /// Emitted when protocol principal is pulled back to this contract.
    event PrincipalRetrieved();

    /// Emitted when protocol principal is (re)deployed into the active vault.
    event PrincipalDeposited(uint256 principal);

    /// Emitted on new user deposit creation.
    event FundsDeposited(uint256 depositId, address depositor, uint256 amountEth);

    /// Emitted when a user successfully withdraws principal.
    event FundsRetrieved(uint256 depositId, address depositor, uint256 amountEth);

    /*//////////////////////////////////////////////////////////////
                       PUBLIC CONSTANTS & VARIABLES
    //////////////////////////////////////////////////////////////*/

    /// @notice Seconds a user deposit remains locked.
    function USER_LOCK_SECS() external view returns (uint32);

    /// @notice CowSwap fee (basis-points, 1 bp = 0.01 %).
    function MAX_FEE_BPS() external view returns (uint16);

    /// @notice CowSwap slippage tolerance (basis-points, 1 bp = 0.01 %).
    function ROUTER_SLIPPAGE_BPS() external view returns (uint16);

    /// @notice CowSwap order validity in seconds.
    function ROUTER_VALIDITY_SECS() external view returns (uint32);

    /// Role IDs used by AccessControl.
    function ADMIN_ROLE() external view returns (bytes32);
    function AUTOMATOR_ROLE() external view returns (bytes32);

    /// External contract references
    function router() external view returns (IEthToBoldRouter);
    function BOLD() external view returns (IERC20);
    function sBOLD() external view returns (ISBOLD);
    function sebaVault() external view returns (IPYBSeba);
    function yieldVault() external view returns (IYieldVault);
    function sebaPool() external view returns (address);

    /// Conversion & yield state
    function activeRouterUid() external view returns (bytes32);
    function pendingBoldConversion() external view returns (uint256);
    function yieldFlowActive() external view returns (bool);
    function lastConversionStartTimestamp() external view returns (uint256);

    /// Principal deployed on behalf of Seba (ETH value)
    function principalValue() external view returns (uint256);

    /// Incrementing deposit counter
    function depositId() external view returns (uint256);

    /// Mapping accessor for deposits
    function deposits(
        uint256 id
    ) external view returns (address depositor, IYieldVault vaultAtDeposit, uint256 amount, uint32 unlockTime);

    /*//////////////////////////////////////////////////////////////
                                ACTIONS
    //////////////////////////////////////////////////////////////*/

    /**
     * @notice Deposit ETH into the manager.
     *         • If `msg.sender == boostPool`: 50 / 50 split — half routed
     *           to CowSwap, half deposited into the strategy vault.
     *         • Else: entire amount deposited & locked under the caller.
     *
     * @dev Emits {DepositReceived}.
     *      Emits {FundsDeposited} for the *user* branch.
     *
     * Reverts {EmptyDeposit}.
     */
    function depositFunds() external payable;

    /**
     * @notice Withdraw the caller’s locked principal once the lock expires.
     * @param id  The deposit ID obtained from {FundsDeposited}.
     *
     * @dev Reverts {NonExistingDeposit}, {InvalidDepositor},
     *      {DepositStillLocked}.
     *      Emits {FundsRetrieved}.
     */
    function retrieveFunds(uint256 id) external;

    /**
     * @notice House-keeping for the ETH→BOLD→sBOLD pipeline:
     *         - Cancel & refund expired CowSwap order (if any),
     *         - Convert any held BOLD into sBOLD & top-up SebaVault,
     *         - Start a new CowSwap order if ETH is pending.
     *
     * @dev Emits {BoldConversionFinalised} and/or {BoldConversionStarted}.
     */
    function runBoldConversion(uint256 feeAmount) external;

    /**
     * @notice Claim yield from the active vault.
     *         • If `yieldFlowActive == false`: auto-compound back into vault.
     *         • Else: add ETH to pending conversion for SebaVault top-up.
     *
     * @dev Restricted to role `AUTOMATOR_ROLE`.
     *      Emits {YieldDistributed}.
     */
    function distributeYield() external;

    /**
     * @notice One-time switch that routes *future* yield to SebaVault
     *         via the sBOLD conversion path.
     *
     * @dev Reverts {YieldFlowAlreadyActivated}.
     *      Emits {YieldFlowActivated}.
     *      Only an `ADMIN_ROLE` holder may call.
     */
    function activateYieldFlow() external;

    /* ----------------------------- Admin ops --------------------------- */

    /**
     * @notice Point the manager at a new strategy vault.
     *         Existing principal is pulled first.
     */
    function setYieldVault(address _yieldVault) external;

    /// Retrieve protocol-owned principal from the current vault.
    function retrievePrincipalFromYieldVault() external;

    /// Deposit any idle principal held by this contract into the vault.
    function depositPrincipalIntoYieldVault() external;

    /// Adjust CowSwap slippage tolerance (basis-points).
    function setRouterSlippageBps(uint16 _bps) external;

    /// Adjust CowSwap order validity window (seconds).
    function setRouterValiditySecs(uint32 _secs) external;

    /// Adjust CowSwap Max fee tolerance (basis-points).
    function setMaxFeeBPS(uint16 _bps) external;
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

/**
 * @title IPYBSeba
 * @notice Interface for the Perpetual Seba vault.
 * @dev Extends an ERC4626-style vault. It adds functions for topping up and distributing shares, as well as setting the BoostPool.
 */
interface IPYBSeba {
    /*//////////////////////////////////////////////////////////////
                              ERRORS
    //////////////////////////////////////////////////////////////*/

    /// @notice Thrown when an address parameter is the zero address.
    error InvalidAddress();
    /// @notice Thrown when a function is called by an address other than the SebaPool.
    /// @param sender The address that attempted the call.
    error NotSebaPool(address sender);
    /// @notice Thrown when a deposit or mint operation would result in zero shares.
    error ZeroShares();
    /// @notice Thrown when a deposit or mint operation would result in zero assets.
    error ZeroAssets();
    /// @notice Thrown when a deposit or mint would cause the total share supply to exceed the cap.
    error SupplyCapExceeded();
    /// @notice Thrown when a deposit is tried as it is not allowed.
    error DepositNotAllowed();
    /// @notice Thrown when a mint is tried as it is not allowed.
    error MintNotAllowed();

    /*//////////////////////////////////////////////////////////////
                              EVENTS
    //////////////////////////////////////////////////////////////*/

    /// @notice Emitted when the SebaPool address is updated.
    /// @param sebaPool The new SebaPool address.
    event SebaPoolChanged(address indexed sebaPool);
    /// @notice Emitted when the vault is topped up.
    /// @param sender The address initiating the topup.
    /// @param amount The amount of assets transferred.
    event Topup(address indexed sender, uint256 amount);
    /// @notice Emitted when shares are distributed.
    /// @param receiver The address receiving the shares.
    /// @param shares The number of shares distributed.
    event SharesDistributed(address indexed receiver, uint256 shares);

    /*//////////////////////////////////////////////////////////////
                         PUBLIC VARIABLES (Getters)
    //////////////////////////////////////////////////////////////*/

    /// @notice Returns the total assets held in the vault.
    function assetTotal() external view returns (uint256);
    /// @notice Returns the SebaPool contract address.
    function sebaPool() external view returns (address);

    /// @notice The role identifier for administrative functions.
    function ADMIN_ROLE() external view returns (bytes32);

    /*//////////////////////////////////////////////////////////////
                              FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /**
     * @notice Tops up the vault by transferring assets from the caller.
     * @dev See {topup} in the contract.
     * @param amount The amount of assets to top up.
     */
    function topup(uint256 amount) external;

    /**
     * @notice Distributes yield-bearing shares to a receiver.
     * @dev Can only be called by the BoostPool. Emits a {SharesDistributed} event.
     * @param receiver The address to receive shares.
     * @param shares The number of shares to distribute.
     */
    function distributeShares(address receiver, uint256 shares) external;

    /**
     * @notice Sets the SebaPool address.
     * @dev Reverts if the new address is zero. Emits a {SebaPoolChanged} event.
     * @param _sebaPool The new SebaPool address.
     */
    function setSebaPool(address _sebaPool) external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/IAccessControl.sol)

pragma solidity ^0.8.20;

/**
 * @dev External interface of AccessControl declared to support ERC-165 detection.
 */
interface IAccessControl {
    /**
     * @dev The `account` is missing a role.
     */
    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);

    /**
     * @dev The caller of a function is not the expected one.
     *
     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
     */
    error AccessControlBadConfirmation();

    /**
     * @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.
     */
    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. This account bears the admin role (for the granted role).
     * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
     */
    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 `callerConfirmation`.
     */
    function renounceRole(bytes32 role, address callerConfirmation) external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;

import {IERC165} from "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC-165 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);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

interface IPoap {
    function tokenEvent(uint256 poapId) external view returns (uint256);
    function ownerOf(uint256 poapId) external view returns (address);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import { IEthFlow } from "src/vendor/cowswap/IEthFlow.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { AggregatorV3Interface } from "src/vendor/chainlink/AggregatorV3Interface.sol";

/**
 * @title IEthToBoldRouter
 * @notice Interface for the router that swaps ETH→BOLD using CowSwap Eth-flow,
 *         sizes `minOut` via Chainlink ETH/USD, tracks a single open intent per initiator,
 *         and exposes helpers to query or cancel the intent.
 */
interface IEthToBoldRouter {
    /*//////////////////////////////////////////////////////////////
                               ERRORS
    //////////////////////////////////////////////////////////////*/

    /// @notice Thrown when an address parameter is the zero address.
    error InvalidAddress();
    /// @notice Thrown when no ETH is sent for a swap.
    error NoEthSent();
    /// @notice Thrown when slippage bps is invalid or exceeds the max.
    error InvalidSlippage(uint256 slippage, uint256 maxSlippage);
    /// @notice Thrown when fee bps is invalid or exceeds the max.
    error InvalidFee(uint256 fee, uint256 maxFee);
    /// @notice Thrown when an initiator already has an open order.
    error OrderAlreadyOpen();
    /// @notice Thrown when the Chainlink price is non-positive.
    error OraclePriceInvalid(int256 px);
    /// @notice Thrown when the Chainlink price is stale.
    error StaleOracle();
    /// @notice Thrown when cancel is invoked with no active order.
    error NoActiveOrder();
    /// @notice Thrown when refunding ETH to the initiator fails.
    error FailedETHRefund();

    /*//////////////////////////////////////////////////////////////
                                EVENTS
    //////////////////////////////////////////////////////////////*/

    /// @notice Emitted when an intent is created on Eth-flow.
    /// @param initiator The initiating address (also the receiver of BOLD).
    /// @param ethIn The ETH amount committed.
    /// @param minBoldOut The minimum BOLD the order will accept.
    /// @param uid The 56-byte order UID.
    /// @param validTo Expiry timestamp used by the order.
    event IntentCreated(address indexed initiator, uint256 ethIn, uint256 minBoldOut, bytes32 uid, uint32 validTo);

    /// @notice Emitted when an open intent is actively cancelled.
    /// @param initiator The initiator cancelling their order.
    /// @param uid The order UID.
    /// @param ethRefunded Any ETH refunded back to the initiator.
    /// @param boldReceived Any BOLD received as results of succesful intent solving
    event IntentFinalized(address indexed initiator, bytes32 uid, uint256 ethRefunded, uint256 boldReceived);

    /*//////////////////////////////////////////////////////////////
                               STRUCTS
    //////////////////////////////////////////////////////////////*/

    /// @notice Local tracking for a single open order per initiator.
    struct Order {
        address initiator; // the calling address
        uint256 ethAmount; // telemetry/reference only
        bytes32 uid; // 56-byte order UID
        bool active; // order is open in our local view
        IEthFlow.Data data; // Intent data
    }

    /*//////////////////////////////////////////////////////////////
                       PUBLIC CONSTANTS & VARIABLES
    //////////////////////////////////////////////////////////////*/

    /// Role IDs used by AccessControl.
    function ADMIN_ROLE() external view returns (bytes32);
    function YIELD_MANAGER_ROLE() external view returns (bytes32);

    /// @notice Returns the CowSwap Eth-flow contract.
    function ETH_FLOW() external view returns (IEthFlow);

    /// @notice Returns the BOLD ERC-20 token.
    function BOLD() external view returns (IERC20);

    /// @notice Public getter for the pending order.
    function order()
        external
        view
        returns (address initiator, uint256 ethAmount, bytes32 uid, bool active, IEthFlow.Data memory data);

    /*//////////////////////////////////////////////////////////////
                                FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /**
     * @notice Swap caller’s ETH→BOLD via Eth-flow.
     * @dev Uses Chainlink ETH/USD to size `minOut` with the provided slippage bps and validity.
     *      Reverts with {NoEthSent}, {InvalidSlippage}, {OrderAlreadyOpen},
     *      {OraclePriceInvalid}, {StaleOracle} on failure.
     * @param minBoldBeforeSlippage Minimum amount of BOLD to expect before slippage taken into account.
     * @param slippageBps Maximum slippage in basis points (0 … 9,999).
     * @param validity Validity window (seconds) added to current timestamp.
     * @return uid The 56-byte UID of the created order.
     */
    function swapExactEthForBold(
        uint256 minBoldBeforeSlippage,
        uint16 slippageBps,
        uint32 validity
    ) external payable returns (bytes32 uid);

    /**
     * @notice Finalize the caller’s open intent and returns ETH and/or BOLD. If already filled/expired, closes local state without reverting.
     */
    function finalizeIntent() external;
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

/// @notice vault-specific interface for sBOLD.
interface ISBOLD {
    // --- Vault-specific methods ---
    /// Deposits BOLD and mints sBOLD shares to msg.sender.
    function deposit(uint256 boldAmount, address receiver) external returns (uint256 sharesMinted);

    /// Withdraws BOLD by burning sBOLD and sending it to the receiver.
    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

/**
 * @title IYieldVault
 * @notice Minimal interface that any yield-strategy vault must implement for Seba’s
 *         ecosystem. A vault manages principal (in underlying vault asset terms) and can:
 *         ① accept deposits, ② realise and forward yield, and ③ allow principal retrieval.
 * @dev Every strategy-specific vault (e.g., Beefy, Aave, Compound) must implement
 *      this interface so it can be plugged into the Seba YieldManager.
 */
interface IYieldVault {
    /*//////////////////////////////////////////////////////////////
                                FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /**
     * @notice Deposit ETH into the strategy.
     * @dev The caller (usually a YieldManager) transfers ETH with the call.
     *      Implementations should convert / invest as needed and return
     *      the ETH-denominated value credited as principal.
     * @return depositValue Value (in unerlying vault asset terms) accounted as principal.
     */
    function deposit() external payable returns (uint256 depositValue);

    /**
     * @notice Claim strategy yield and transfer it back to the caller
     *         (either auto-compounded or forwarded on, depending on the caller’s logic).
     * @dev Implementations decide what constitutes “yield” versus principal.
     */
    function claimYield() external;

    /**
     * @notice Retrieve an arbitrary slice of principal, denominated in the underlying vault asset.
     * @param depositValue Amount of principal (underlying vault asset terms) requested for return.
     */
    function retrievePrincipal(uint256 depositValue) external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * 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[ERC section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IEthFlow {
    struct Data {
        /// @dev The address of the token that should be bought for ETH. It follows the same format as in the CoW Swap
        /// contracts, meaning that the token GPv2Transfer.BUY_ETH_ADDRESS (0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
        /// represents native ETH (and should most likely not be used in this context).
        IERC20 buyToken;
        /// @dev The address that should receive the proceeds from the order. Note that using the address
        /// GPv2Order.RECEIVER_SAME_AS_OWNER (i.e., the zero address) as the receiver is not allowed.
        address receiver;
        /// @dev The exact amount of ETH that should be sold in this order.
        uint256 sellAmount;
        /// @dev The minimum amount of buyToken that should be received to settle this order.
        uint256 buyAmount;
        /// @dev Extra data to include in the order. It is used by the CoW Swap infrastructure as extra information on
        /// the order and has no direct effect on on-chain execution.
        bytes32 appData;
        /// @dev The exact amount of ETH that should be paid by the user to the CoW Swap contract after the order is
        /// settled.
        uint256 feeAmount;
        /// @dev The last timestamp in seconds from which the order can be settled (order cannot resolve after this timestamp).
        uint32 validTo;
        /// @dev Flag indicating whether the order is fill-or-kill or can be filled partially.
        bool partiallyFillable;
        /// @dev quoteId The quote id obtained from the CoW Swap API to lock in the current price. It is not directly
        /// used by any onchain component but is part of the information emitted onchain on order creation and may be
        /// required for an order to be automatically picked up by the CoW Swap orderbook.
        int64 quoteId;
    }
    function createOrder(Data calldata order) external payable returns (bytes32 orderHash);

    function invalidateOrder(Data calldata order) external;
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

interface AggregatorV3Interface {
    function latestRoundData() external view returns (uint80, int256 answer, uint256, uint256 updatedAt, uint80);
    function decimals() external view returns (uint8);
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
    "forge-std/=node_modules/forge-std/",
    "@prb/test/=node_modules/@prb/test/src/",
    "@uniswap/v3-core/=node_modules/@uniswap/v3-core/\",/",
    "@uniswap/v3-periphery/=node_modules/@uniswap/v3-periphery/\"/",
    "base64-sol/=node_modules/base64-sol/",
    "solmate/=node_modules/solmate/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 10000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": false
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": false
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_automator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"uint256","name":"validatorId","type":"uint256"}],"name":"GraduationPeriodNotOver","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256","name":"poapID","type":"uint256"}],"name":"NonEligibleStaker","type":"error"},{"inputs":[{"internalType":"uint256","name":"validatorId","type":"uint256"}],"name":"ValidatorAlreadyGraduated","type":"error"},{"inputs":[{"internalType":"uint256","name":"validatorId","type":"uint256"}],"name":"ValidatorAlreadySubscribed","type":"error"},{"inputs":[{"internalType":"uint256","name":"validatorId","type":"uint256"}],"name":"ValidatorNotSubscribed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"donationAmount","type":"uint256"}],"name":"EtherReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"yieldManager","type":"address"}],"name":"RewardsSwept","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_sebaVault","type":"address"}],"name":"SebaVaultSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"withdrawalAddress","type":"address"},{"indexed":true,"internalType":"address","name":"poolRecipient","type":"address"}],"name":"SetRewardRecipient","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":true,"internalType":"uint256","name":"validatorId","type":"uint256"}],"name":"SubscribeValidator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"validatorId","type":"uint256"},{"indexed":true,"internalType":"address","name":"withdrawalAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"attestationPoints","type":"uint256"}],"name":"ValidatorGraduated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"yieldManager","type":"address"}],"name":"YieldManagerSet","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AUTOMATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GRADUATION_DURATION_IN_BLOCKS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_validatorId","type":"uint256"},{"internalType":"address","name":"_withdrawalAddress","type":"address"},{"internalType":"uint256","name":"_attestationPoints","type":"uint256"}],"name":"graduateValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sebaVault","outputs":[{"internalType":"contract IPYBSeba","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardAddress","type":"address"}],"name":"setRewardRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sebaVault","type":"address"}],"name":"setSebaVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_yieldManager","type":"address"}],"name":"setYieldManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_validatorId","type":"uint64"}],"name":"subscribeValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64[]","name":"_validatorIdArray","type":"uint64[]"}],"name":"subscribeValidators","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sweepRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"validatorIsGraduated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"validatorRegistrationBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yieldManager","outputs":[{"internalType":"contract IYieldManager","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

608060405234801561000f575f5ffd5b5060405161150538038061150583398101604081905261002e916101fc565b6001600160a01b0382166100555760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03811661007c5760405163e6c4247b60e01b815260040160405180910390fd5b6100935f5160206114e55f395f51905f52836100ee565b506100ab5f5160206114e55f395f51905f5280610197565b6100c25f5160206114c55f395f51905f52826100ee565b506100e75f5160206114c55f395f51905f525f5160206114e55f395f51905f52610197565b505061022d565b5f828152602081815260408083206001600160a01b038516845290915281205460ff1661018e575f838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556101463390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610191565b505f5b92915050565b5f82815260208190526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b80516001600160a01b03811681146101f7575f5ffd5b919050565b5f5f6040838503121561020d575f5ffd5b610216836101e1565b9150610224602084016101e1565b90509250929050565b61128b8061023a5f395ff3fe608060405260043610610174575f3560e01c8063914be426116100ca578063c1e4d0341161007e578063e521136f11610058578063e521136f146104b1578063f372c0c9146104d0578063f6c077201461051157610174565b8063c1e4d0341461044b578063c7bb52641461045f578063d547741f1461049257610174565b8063a217fddf116100af578063a217fddf146103fa578063b9cd552e1461040d578063ba3686771461042c57610174565b8063914be4261461039557806391d14854146103ab57610174565b80635bc375341161012c57806374ce962c1161010657806374ce962c146102f257806375b238fc1461031157806380b7af181461034457610174565b80635bc37534146102895780635f447039146102a8578063600860c9146102d357610174565b80632f2ff15d1161015d5780632f2ff15d1461021b57806336568abe1461023c57806337c28bd71461025b57610174565b806301ffc9a7146101ab578063248a9ca3146101df575b60405134815233907f1e57e3bb474320be3d2c77138f75b7c3941292d647f5f9634e33a8e94e0e069b9060200160405180910390a2005b3480156101b6575f5ffd5b506101ca6101c5366004611093565b61053d565b60405190151581526020015b60405180910390f35b3480156101ea575f5ffd5b5061020d6101f93660046110d9565b5f9081526020819052604090206001015490565b6040519081526020016101d6565b348015610226575f5ffd5b5061023a610235366004611118565b6105d5565b005b348015610247575f5ffd5b5061023a610256366004611118565b6105ff565b348015610266575f5ffd5b506101ca6102753660046110d9565b60056020525f908152604090205460ff1681565b348015610294575f5ffd5b5061023a6102a3366004611142565b61065d565b3480156102b3575f5ffd5b5061020d6102c23660046110d9565b60046020525f908152604090205481565b3480156102de575f5ffd5b5061023a6102ed3660046111b3565b6107db565b3480156102fd575f5ffd5b5061023a61030c3660046111e6565b610a5e565b34801561031c575f5ffd5b5061020d7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177581565b34801561034f575f5ffd5b506002546103709073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d6565b3480156103a0575f5ffd5b5061020d6214103881565b3480156103b6575f5ffd5b506101ca6103c5366004611118565b5f9182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b348015610405575f5ffd5b5061020d5f81565b348015610418575f5ffd5b5061023a6104273660046111ff565b610b44565b348015610437575f5ffd5b5061023a6104463660046111e6565b610be5565b348015610456575f5ffd5b5061023a610cd6565b34801561046a575f5ffd5b5061020d7f61e61406bf21d7b87d4add4290d44cb24547d0d059db9e4a1b66dcce07fc3c8381565b34801561049d575f5ffd5b5061023a6104ac366004611118565b610daf565b3480156104bc575f5ffd5b5061023a6104cb3660046111e6565b610dd3565b3480156104db575f5ffd5b506103706104ea3660046111e6565b60036020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b34801561051c575f5ffd5b506001546103709073ffffffffffffffffffffffffffffffffffffffff1681565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806105cf57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f828152602081905260409020600101546105ef81610e4e565b6105f98383610e58565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8116331461064e576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106588282610f51565b505050565b5f5b818110156106585760045f84848481811061067c5761067c611226565b905060200201602081019061069191906111ff565b67ffffffffffffffff1681526020019081526020015f20545f1461071a578282828181106106c1576106c1611226565b90506020020160208101906106d691906111ff565b6040517fefc96dd200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024015b60405180910390fd5b4360045f85858581811061073057610730611226565b905060200201602081019061074591906111ff565b67ffffffffffffffff16815260208101919091526040015f205582828281811061077157610771611226565b905060200201602081019061078691906111ff565b67ffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f0dc4c226375ad0712bc916ae8ea0b8ff4fb833645af4f6de578e882efce9b22e60405160405180910390a360010161065f565b7f61e61406bf21d7b87d4add4290d44cb24547d0d059db9e4a1b66dcce07fc3c8361080581610e4e565b5f84815260046020526040812054900361084e576040517f189df75100000000000000000000000000000000000000000000000000000000815260048101859052602401610711565b5f8481526005602052604090205460ff1615610899576040517f8dacea0400000000000000000000000000000000000000000000000000000000815260048101859052602401610711565b5f848152600460205260409020546108b5906214103890611253565b4310156108f1576040517f4b186c3b00000000000000000000000000000000000000000000000000000000815260048101859052602401610711565b73ffffffffffffffffffffffffffffffffffffffff8381165f9081526003602052604090205416156109485773ffffffffffffffffffffffffffffffffffffffff9283165f90815260036020526040902054909216915b5f848152600560205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091555490517fdebcf0e500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590529091169063debcf0e5906044015f604051808303815f87803b1580156109f1575f5ffd5b505af1158015610a03573d5f5f3e3d5ffd5b505050508273ffffffffffffffffffffffffffffffffffffffff16847f9afc937962cd7f390d5676ea35985ece35bcbb4f89adfa716c4410e583272ae784604051610a5091815260200190565b60405180910390a350505050565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775610a8881610e4e565b73ffffffffffffffffffffffffffffffffffffffff8216610ad5576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517fbf6e6f9af4c6e0e03c9cb258394f4674cf0ad0c2cb35aa060624a71b07ddcd19905f90a25050565b67ffffffffffffffff81165f9081526004602052604090205415610ba0576040517fefc96dd200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610711565b67ffffffffffffffff81165f818152600460205260408082204390555133917f0dc4c226375ad0712bc916ae8ea0b8ff4fb833645af4f6de578e882efce9b22e91a350565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775610c0f81610e4e565b73ffffffffffffffffffffffffffffffffffffffff8216610c5c576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040519081527f6b1912589fc89f5903656ca4a8fec2932fde39e0f2cf4d7283a41e89a5b7e7cc9060200160405180910390a15050565b478015610dac5760025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e2c41dbc826040518263ffffffff1660e01b81526004015f604051808303818588803b158015610d44575f5ffd5b505af1158015610d56573d5f5f3e3d5ffd5b505060025460405185815273ffffffffffffffffffffffffffffffffffffffff90911693507ff4a5e408cf15ff8c7c9acfdb2b763107b19df5f5755f72a78647ae1d719ad8669250602001905060405180910390a25b50565b5f82815260208190526040902060010154610dc981610e4e565b6105f98383610f51565b335f8181526003602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590519092917fc6b66e0e282673c442421e1c6b89458b7631f26f5dcd0b2b216c45831ca1d7d591a350565b610dac813361100a565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16610f4a575f8381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff86168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610ee83390565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45060016105cf565b505f6105cf565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff1615610f4a575f8381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8616808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45060016105cf565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661108f576040517fe2517d3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260248101839052604401610711565b5050565b5f602082840312156110a3575f5ffd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146110d2575f5ffd5b9392505050565b5f602082840312156110e9575f5ffd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611113575f5ffd5b919050565b5f5f60408385031215611129575f5ffd5b82359150611139602084016110f0565b90509250929050565b5f5f60208385031215611153575f5ffd5b823567ffffffffffffffff811115611169575f5ffd5b8301601f81018513611179575f5ffd5b803567ffffffffffffffff81111561118f575f5ffd5b8560208260051b84010111156111a3575f5ffd5b6020919091019590945092505050565b5f5f5f606084860312156111c5575f5ffd5b833592506111d5602085016110f0565b929592945050506040919091013590565b5f602082840312156111f6575f5ffd5b6110d2826110f0565b5f6020828403121561120f575f5ffd5b813567ffffffffffffffff811681146110d2575f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b808201808211156105cf577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd61e61406bf21d7b87d4add4290d44cb24547d0d059db9e4a1b66dcce07fc3c83a49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c217750000000000000000000000005ebaaa3e84f9595fbf787a71c3caad97d370bc280000000000000000000000008fbbc54d49b23f5b397dfe62ad2fb0e09cbe9379

Deployed Bytecode

0x608060405260043610610174575f3560e01c8063914be426116100ca578063c1e4d0341161007e578063e521136f11610058578063e521136f146104b1578063f372c0c9146104d0578063f6c077201461051157610174565b8063c1e4d0341461044b578063c7bb52641461045f578063d547741f1461049257610174565b8063a217fddf116100af578063a217fddf146103fa578063b9cd552e1461040d578063ba3686771461042c57610174565b8063914be4261461039557806391d14854146103ab57610174565b80635bc375341161012c57806374ce962c1161010657806374ce962c146102f257806375b238fc1461031157806380b7af181461034457610174565b80635bc37534146102895780635f447039146102a8578063600860c9146102d357610174565b80632f2ff15d1161015d5780632f2ff15d1461021b57806336568abe1461023c57806337c28bd71461025b57610174565b806301ffc9a7146101ab578063248a9ca3146101df575b60405134815233907f1e57e3bb474320be3d2c77138f75b7c3941292d647f5f9634e33a8e94e0e069b9060200160405180910390a2005b3480156101b6575f5ffd5b506101ca6101c5366004611093565b61053d565b60405190151581526020015b60405180910390f35b3480156101ea575f5ffd5b5061020d6101f93660046110d9565b5f9081526020819052604090206001015490565b6040519081526020016101d6565b348015610226575f5ffd5b5061023a610235366004611118565b6105d5565b005b348015610247575f5ffd5b5061023a610256366004611118565b6105ff565b348015610266575f5ffd5b506101ca6102753660046110d9565b60056020525f908152604090205460ff1681565b348015610294575f5ffd5b5061023a6102a3366004611142565b61065d565b3480156102b3575f5ffd5b5061020d6102c23660046110d9565b60046020525f908152604090205481565b3480156102de575f5ffd5b5061023a6102ed3660046111b3565b6107db565b3480156102fd575f5ffd5b5061023a61030c3660046111e6565b610a5e565b34801561031c575f5ffd5b5061020d7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177581565b34801561034f575f5ffd5b506002546103709073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d6565b3480156103a0575f5ffd5b5061020d6214103881565b3480156103b6575f5ffd5b506101ca6103c5366004611118565b5f9182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b348015610405575f5ffd5b5061020d5f81565b348015610418575f5ffd5b5061023a6104273660046111ff565b610b44565b348015610437575f5ffd5b5061023a6104463660046111e6565b610be5565b348015610456575f5ffd5b5061023a610cd6565b34801561046a575f5ffd5b5061020d7f61e61406bf21d7b87d4add4290d44cb24547d0d059db9e4a1b66dcce07fc3c8381565b34801561049d575f5ffd5b5061023a6104ac366004611118565b610daf565b3480156104bc575f5ffd5b5061023a6104cb3660046111e6565b610dd3565b3480156104db575f5ffd5b506103706104ea3660046111e6565b60036020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b34801561051c575f5ffd5b506001546103709073ffffffffffffffffffffffffffffffffffffffff1681565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806105cf57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f828152602081905260409020600101546105ef81610e4e565b6105f98383610e58565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8116331461064e576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106588282610f51565b505050565b5f5b818110156106585760045f84848481811061067c5761067c611226565b905060200201602081019061069191906111ff565b67ffffffffffffffff1681526020019081526020015f20545f1461071a578282828181106106c1576106c1611226565b90506020020160208101906106d691906111ff565b6040517fefc96dd200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024015b60405180910390fd5b4360045f85858581811061073057610730611226565b905060200201602081019061074591906111ff565b67ffffffffffffffff16815260208101919091526040015f205582828281811061077157610771611226565b905060200201602081019061078691906111ff565b67ffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f0dc4c226375ad0712bc916ae8ea0b8ff4fb833645af4f6de578e882efce9b22e60405160405180910390a360010161065f565b7f61e61406bf21d7b87d4add4290d44cb24547d0d059db9e4a1b66dcce07fc3c8361080581610e4e565b5f84815260046020526040812054900361084e576040517f189df75100000000000000000000000000000000000000000000000000000000815260048101859052602401610711565b5f8481526005602052604090205460ff1615610899576040517f8dacea0400000000000000000000000000000000000000000000000000000000815260048101859052602401610711565b5f848152600460205260409020546108b5906214103890611253565b4310156108f1576040517f4b186c3b00000000000000000000000000000000000000000000000000000000815260048101859052602401610711565b73ffffffffffffffffffffffffffffffffffffffff8381165f9081526003602052604090205416156109485773ffffffffffffffffffffffffffffffffffffffff9283165f90815260036020526040902054909216915b5f848152600560205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091555490517fdebcf0e500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590529091169063debcf0e5906044015f604051808303815f87803b1580156109f1575f5ffd5b505af1158015610a03573d5f5f3e3d5ffd5b505050508273ffffffffffffffffffffffffffffffffffffffff16847f9afc937962cd7f390d5676ea35985ece35bcbb4f89adfa716c4410e583272ae784604051610a5091815260200190565b60405180910390a350505050565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775610a8881610e4e565b73ffffffffffffffffffffffffffffffffffffffff8216610ad5576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517fbf6e6f9af4c6e0e03c9cb258394f4674cf0ad0c2cb35aa060624a71b07ddcd19905f90a25050565b67ffffffffffffffff81165f9081526004602052604090205415610ba0576040517fefc96dd200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610711565b67ffffffffffffffff81165f818152600460205260408082204390555133917f0dc4c226375ad0712bc916ae8ea0b8ff4fb833645af4f6de578e882efce9b22e91a350565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775610c0f81610e4e565b73ffffffffffffffffffffffffffffffffffffffff8216610c5c576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040519081527f6b1912589fc89f5903656ca4a8fec2932fde39e0f2cf4d7283a41e89a5b7e7cc9060200160405180910390a15050565b478015610dac5760025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e2c41dbc826040518263ffffffff1660e01b81526004015f604051808303818588803b158015610d44575f5ffd5b505af1158015610d56573d5f5f3e3d5ffd5b505060025460405185815273ffffffffffffffffffffffffffffffffffffffff90911693507ff4a5e408cf15ff8c7c9acfdb2b763107b19df5f5755f72a78647ae1d719ad8669250602001905060405180910390a25b50565b5f82815260208190526040902060010154610dc981610e4e565b6105f98383610f51565b335f8181526003602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590519092917fc6b66e0e282673c442421e1c6b89458b7631f26f5dcd0b2b216c45831ca1d7d591a350565b610dac813361100a565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16610f4a575f8381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff86168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610ee83390565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45060016105cf565b505f6105cf565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff1615610f4a575f8381526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8616808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45060016105cf565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661108f576040517fe2517d3f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260248101839052604401610711565b5050565b5f602082840312156110a3575f5ffd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146110d2575f5ffd5b9392505050565b5f602082840312156110e9575f5ffd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611113575f5ffd5b919050565b5f5f60408385031215611129575f5ffd5b82359150611139602084016110f0565b90509250929050565b5f5f60208385031215611153575f5ffd5b823567ffffffffffffffff811115611169575f5ffd5b8301601f81018513611179575f5ffd5b803567ffffffffffffffff81111561118f575f5ffd5b8560208260051b84010111156111a3575f5ffd5b6020919091019590945092505050565b5f5f5f606084860312156111c5575f5ffd5b833592506111d5602085016110f0565b929592945050506040919091013590565b5f602082840312156111f6575f5ffd5b6110d2826110f0565b5f6020828403121561120f575f5ffd5b813567ffffffffffffffff811681146110d2575f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b808201808211156105cf577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd

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

0000000000000000000000005ebaaa3e84f9595fbf787a71c3caad97d370bc280000000000000000000000008fbbc54d49b23f5b397dfe62ad2fb0e09cbe9379

-----Decoded View---------------
Arg [0] : _admin (address): 0x5EBAAA3E84F9595fBF787A71C3CAad97d370BC28
Arg [1] : _automator (address): 0x8FbBC54D49b23F5b397dfE62AD2Fb0E09Cbe9379

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000005ebaaa3e84f9595fbf787a71c3caad97d370bc28
Arg [1] : 0000000000000000000000008fbbc54d49b23f5b397dfe62ad2fb0e09cbe9379


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ 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.