contract CyberbridgeETH {

    Access public access;

    bool public isActive = true;

    event onDeposit(address from, uint256 amount, bytes32 token);
    event onWithdraw(address to, uint256 amount, bytes32 token);

    modifier onlyAdmin() {
        require(access.isAdmin(msg.sender), "not admin");
        _;
    }

    modifier onlyAdminOrService() {
        require(access.isAdmin(msg.sender) || access.isService(msg.sender), "not admin/service");
        _;
    }

    modifier onlyValidAddress(address addr) {
        require(addr != address(0x0), "null address");
        _;
    }

    modifier onlyActiveContract() {
        require(isActive, "inactive contract");
        _;
    }

    constructor(address accessAddr) public onlyValidAddress(accessAddr) {
        access = Access(accessAddr);
    }

    function setActive(bool active) public onlyAdmin {
        isActive = active;
    }

    function refill() public onlyAdmin payable { }

    function drain(address recipientAddr) public onlyAdmin onlyValidAddress(recipientAddr) {
        uint256 ethAmount = address(this).balance;
        if (ethAmount > 0) {
            recipientAddr.transfer(ethAmount);
        }
    }

    // ---

    function deposit(bytes32 token) public onlyActiveContract payable {
        require(msg.value > 0, "zero amount");
        emit onDeposit(msg.sender, msg.value, token);
    }

    function withdraw(address to, uint256 amount, bytes32 token) public onlyActiveContract onlyAdminOrService onlyValidAddress(to) {
        require(amount > 0, "zero amount");
        require(address(this).balance >= amount, "not enough funds");
        to.transfer(amount);
        emit onWithdraw(to, amount, token);
    }
}
// CyberbridgeETH receives ETH deposits
function deposit(bytes32 token) public onlyActiveContract payable {
    require(msg.value > 0, "zero amount");
    emit onDeposit(msg.sender, msg.value, token);
}

// ---