```\nfunction userWithdraw(address to, address user, address token, uint256 dTokenAmount) external nonReentrant allowedToken(token) returns(uint256 amount) {\n        accrueInterest(token);\n        AssetInfo storage info = assetInfo[token];\n        require(dTokenAmount <= IDToken(info.dToken).balanceOf(msg.sender), Errors.DTOKEN_BALANCE_NOT_ENOUGH);\n\n        amount = dTokenAmount.mul(_getExchangeRate(token));//@audit does not check amount value\n        IDToken(info.dToken).burn(msg.sender, dTokenAmount);\n        IERC20(token).safeTransfer(to, amount);\n        info.balance = info.balance - amount;\n\n        // used for calculate user withdraw amount\n        // this function could be called from d3Proxy, so we need "user" param\n        // In the meantime, some users may hope to use this function directly,\n        // to prevent these users fill "user" param with wrong addresses,\n        // we use "msg.sender" param to check.\n        emit UserWithdraw(msg.sender, user, token, amount);\n    }\n```\n