contract Cyberbridge {

    Access public access;

    bool public isActual = true;
    bool public isActive = true;

    event onDeposit(address from, uint256 amount, uint64 userID, bytes32 token);
    event onWithdraw(address to, uint256 amount, uint64 userID, 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), "nil address");
        _;
    }

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

    modifier onlyInactiveContract() {
        require(!isActive, "active contract");
        _;
    }

    modifier onlyActualContract() {
        require(isActual, "outdated contract");
        _;
    }

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

    function deactivate(address ethRecipientAddr) public onlyAdmin onlyValidAddress(ethRecipientAddr) {
        uint256 ethAmount = address(this).balance;
        if (ethAmount > 0) {
            ethRecipientAddr.transfer(ethAmount);
        }
        isActive = false;
        isActual = false;
    }

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

    // ---

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