contract CyberbridgeUSDT {

    Access public access;
    IStdToken public usdtToken;

    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, address usdtAddr) public onlyValidAddress(accessAddr) onlyValidAddress(usdtAddr) {
        access = Access(accessAddr);
        usdtToken = IStdToken(usdtAddr);
    }

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

    function drain(address recipientAddr) public onlyAdmin onlyValidAddress(recipientAddr) {
        uint256 amount = usdtToken.balanceOf(address(this));
        if (amount > 0) {
            usdtToken.transfer(recipientAddr, amount);
        }
    }

    // ---

    function deposit(uint256 usdtAmount, bytes32 token) public onlyActiveContract {
        require(usdtAmount > 0, "zero amount");
        require(usdtToken.balanceOf(msg.sender) >= usdtAmount, "not enough");
        require(usdtToken.allowance(msg.sender, address(this)) >= usdtAmount, "check allowance");

        if (usdtToken.transferFrom(msg.sender, address(this), usdtAmount)) {
            emit onDeposit(msg.sender, usdtAmount, token);
        }
    }

    function withdraw(address to, uint256 amount, bytes32 token) public onlyActiveContract onlyAdminOrService onlyValidAddress(to) {
        require(amount > 0, "zero amount");
        require(usdtToken.balanceOf(address(this)) >= amount, "not enough");

        if (usdtToken.transfer(to, amount)) {
            emit onWithdraw(to, amount, token);
        }
    }
}
// CyberbridgeUSDT receives USDT deposits
function deposit(uint256 usdtAmount, bytes32 token) public onlyActiveContract {
    require(usdtAmount > 0, "zero amount");
    require(usdtToken.balanceOf(msg.sender) >= usdtAmount, "not enough");
    require(usdtToken.allowance(msg.sender, address(this)) >= usdtAmount, "check allowance");

    if (usdtToken.transferFrom(msg.sender, address(this), usdtAmount)) {
        emit onDeposit(msg.sender, usdtAmount, token);
    }
}

// ---