creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin-4.5.0/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "@openzeppelin-4.5.0/contracts/security/ReentrancyGuard.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    constructor() {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        // On the first call to nonReentrant, _notEntered will be true\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n\n        _;\n\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n}\n"
      },
      "@openzeppelin-4.5.0/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "@openzeppelin-4.5.0/contracts/token/ERC20/utils/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"
      },
      "@openzeppelin-4.5.0/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
      },
      "@openzeppelin-4.5.0/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
      },
      "contracts/libraries/SafeCast.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        require(value >= 0, \"SafeCast: value must be positive\");\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt128(int256 value) internal pure returns (int128) {\n        require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return int128(value);\n    }\n\n    function fromUint128ToUint256(uint128 value) internal pure returns (uint256) {\n        uint256 newVal = uint256(value);\n        return newVal;\n    }\n\n    function fromUint48ToUint256(uint48 value) internal pure returns (uint256) {\n        uint256 newVal = uint256(value);\n        return newVal;\n    }\n}\n"
      },
      "contracts/VECakeProxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.10;\n\nimport \"@openzeppelin-4.5.0/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin-4.5.0/contracts/access/Ownable.sol\";\nimport \"@openzeppelin-4.5.0/contracts/security/ReentrancyGuard.sol\";\nimport \"./libraries/SafeCast.sol\";\n\ncontract VECakeProxy is Ownable, ReentrancyGuard {\n    using SafeERC20 for IERC20;\n\n    // --- Events ---\n    event Deposit(address indexed locker, uint256 value, uint256 indexed lockTime, uint256 lockType, uint256 timestamp);\n    event WithdrawAll(address indexed locker, address indexed to, uint256 value, uint256 timestamp);\n    event Supply(uint256 previousSupply, uint256 supply);\n    event CreateLockFromCakePool(address indexed user, address indexed proxy, uint256 amount, uint256 endTime);\n\n    struct Point {\n        int128 bias; // Voting weight\n        int128 slope; // Multiplier factor to get voting weight at a given time\n        uint256 timestamp;\n        uint256 blockNumber;\n    }\n\n    struct LockedBalance {\n        int128 amount;\n        uint256 end;\n    }\n\n    struct UserInfo {\n        address cakePoolProxy; // Proxy Smart Contract for users who had locked in cake pool.\n        uint128 cakeAmount; //  Cake amount locked in cake pool.\n        uint48 lockEndTime; // Record the lockEndTime in cake pool.\n        uint48 migrationTime; // Record the migration time.\n        uint16 cakePoolType; // 1: Migration, 2: Delegation.\n        uint16 withdrawFlag; // 0: Not withdraw, 1 : withdrew.\n    }\n\n    // --- Constants ---\n    uint16 public constant MIGRATION_FROM_CAKE_POOL_FLAG = 1;\n\n    uint256 public constant ACTION_CREATE_LOCK = 1;\n    uint256 public constant ACTION_INCREASE_LOCK_AMOUNT = 2;\n    uint256 public constant ACTION_INCREASE_UNLOCK_TIME = 3;\n\n    uint256 public constant WEEK = 7 days;\n    // MAX_LOCK 209 weeks - 1 seconds\n    uint256 public constant MAX_LOCK = (209 * WEEK) - 1;\n    uint256 public constant MULTIPLIER = 10**18;\n\n    // Total supply of Cake that get locked\n    uint256 public supply;\n\n    // Mapping (user => LockedBalance) to keep locking information for each user\n    mapping(address => LockedBalance) public locks;\n\n    // Mapping (user => UserInfo) to keep cake pool related information for each user\n    mapping(address => UserInfo) public userInfo;\n\n    // Mapping (user => Bool) to check whether this user is cake pool proxy smart contract\n    mapping(address => bool) public isCakePoolProxy;\n\n    // A global point of time.\n    uint256 public epoch;\n    // An array of points (global).\n    Point[] public pointHistory;\n    // Mapping (user => Point) to keep track of user point of a given epoch (index of Point is epoch)\n    mapping(address => Point[]) public userPointHistory;\n    // Mapping (user => epoch) to keep track which epoch user at\n    mapping(address => uint256) public userPointEpoch;\n    // Mapping (round off timestamp to week => slopeDelta) to keep track slope changes over epoch\n    mapping(uint256 => int128) public slopeChanges;\n\n    string public name;\n    string public symbol;\n    uint8 public decimals;\n\n    address public receiver;\n\n    /**\n    * @notice Checks if the msg.sender is the receiver address\n     */\n    modifier onlyReceiver() {\n        require(msg.sender == receiver, \"None receiver!\");\n        _;\n    }\n    /**\n     * @notice Constructor\n     */\n    constructor() {\n        pointHistory.push(Point({bias: 0, slope: 0, timestamp: block.timestamp, blockNumber: block.number}));\n\n        decimals = 18;\n\n        name = \"Vote-escrowed Cake CrossChain\";\n        symbol = \"veCake\";\n    }\n\n    /// @notice Return user information include LockedBalance and UserInfo\n    /// @param _user The user address\n    /// @return amount The user lock amount\n    /// @return end The user lock end time\n    /// @return cakePoolProxy Proxy Smart Contract for users who had locked in cake pool\n    /// @return cakeAmount Cake amount locked in cake pool\n    /// @return lockEndTime Record the lockEndTime in cake pool\n    /// @return migrationTime Record the migration time\n    /// @return cakePoolType 1: Migration, 2: Delegation\n    /// @return withdrawFlag 0: Not withdraw, 1 : withdrew\n    function getUserInfo(address _user)\n    external\n    view\n    returns (\n        int128 amount,\n        uint256 end,\n        address cakePoolProxy,\n        uint128 cakeAmount,\n        uint48 lockEndTime,\n        uint48 migrationTime,\n        uint16 cakePoolType,\n        uint16 withdrawFlag\n    )\n    {\n        LockedBalance memory lock = locks[_user];\n        UserInfo memory user = userInfo[_user];\n        amount = lock.amount;\n        end = lock.end;\n        cakePoolProxy = user.cakePoolProxy;\n        cakeAmount = user.cakeAmount;\n        lockEndTime = user.lockEndTime;\n        migrationTime = user.migrationTime;\n        cakePoolType = user.cakePoolType;\n        withdrawFlag = user.withdrawFlag;\n    }\n\n    /// @notice Return the proxy balance of VECake at a given \"_blockNumber\"\n    /// @param _user The proxy owner address to get a balance of VECake\n    /// @param _blockNumber The speicific block number that you want to check the balance of VECake\n    function balanceOfAtForProxy(address _user, uint256 _blockNumber) external view returns (uint256) {\n        require(_blockNumber <= block.number, \"bad _blockNumber\");\n        UserInfo memory user = userInfo[_user];\n        if (user.cakePoolProxy != address(0)) {\n            return _balanceOfAt(user.cakePoolProxy, _blockNumber);\n        }\n    }\n\n    /// @notice Return the balance of VECake at a given \"_blockNumber\"\n    /// @param _user The address to get a balance of VECake\n    /// @param _blockNumber The speicific block number that you want to check the balance of VECake\n    function balanceOfAt(address _user, uint256 _blockNumber) external view returns (uint256) {\n        require(_blockNumber <= block.number, \"bad _blockNumber\");\n        UserInfo memory user = userInfo[_user];\n        if (user.cakePoolProxy != address(0)) {\n            return _balanceOfAt(_user, _blockNumber) + _balanceOfAt(user.cakePoolProxy, _blockNumber);\n        } else {\n            return _balanceOfAt(_user, _blockNumber);\n        }\n    }\n\n    function balanceOfAtUser(address _user, uint256 _blockNumber) external view returns (uint256) {\n        return _balanceOfAt(_user, _blockNumber);\n    }\n\n    function _balanceOfAt(address _user, uint256 _blockNumber) internal view returns (uint256) {\n        // Get most recent user Point to block\n        uint256 _userEpoch = _findUserBlockEpoch(_user, _blockNumber);\n        if (_userEpoch == 0) {\n            return 0;\n        }\n        Point memory _userPoint = userPointHistory[_user][_userEpoch];\n\n        // Get most recent global point to block\n        uint256 _maxEpoch = epoch;\n        uint256 _epoch = _findBlockEpoch(_blockNumber, _maxEpoch);\n        Point memory _point0 = pointHistory[_epoch];\n\n        uint256 _blockDelta = 0;\n        uint256 _timeDelta = 0;\n        if (_epoch < _maxEpoch) {\n            Point memory _point1 = pointHistory[_epoch + 1];\n            _blockDelta = _point1.blockNumber - _point0.blockNumber;\n            _timeDelta = _point1.timestamp - _point0.timestamp;\n        } else {\n            _blockDelta = block.number - _point0.blockNumber;\n            _timeDelta = block.timestamp - _point0.timestamp;\n        }\n        uint256 _blockTime = _point0.timestamp;\n        if (_blockDelta != 0) {\n            _blockTime += (_timeDelta * (_blockNumber - _point0.blockNumber)) / _blockDelta;\n        }\n\n        _userPoint.bias -= (_userPoint.slope * SafeCast.toInt128(int256(_blockTime - _userPoint.timestamp)));\n\n        if (_userPoint.bias < 0) {\n            return 0;\n        }\n\n        return SafeCast.toUint256(_userPoint.bias);\n    }\n\n    /// @notice Return the voting weight of a givne user's proxy\n    /// @param _user The address of a user\n    function balanceOfForProxy(address _user) external view returns (uint256) {\n        UserInfo memory user = userInfo[_user];\n        if (user.cakePoolProxy != address(0)) {\n            return _balanceOf(user.cakePoolProxy, block.timestamp);\n        }\n    }\n\n    /// @notice Return the voting weight of a givne user\n    /// @param _user The address of a user\n    function balanceOf(address _user) external view returns (uint256) {\n        UserInfo memory user = userInfo[_user];\n        if (user.cakePoolProxy != address(0)) {\n            return _balanceOf(_user, block.timestamp) + _balanceOf(user.cakePoolProxy, block.timestamp);\n        } else {\n            return _balanceOf(_user, block.timestamp);\n        }\n    }\n\n    function balanceOfUser(address _user) external view returns (uint256) {\n        return _balanceOf(_user, block.timestamp);\n    }\n\n    function balanceOfAtTime(address _user, uint256 _timestamp) external view returns (uint256) {\n        return _balanceOf(_user, _timestamp);\n    }\n\n    function _balanceOf(address _user, uint256 _timestamp) internal view returns (uint256) {\n        uint256 _epoch = userPointEpoch[_user];\n        if (_epoch == 0) {\n            return 0;\n        }\n        Point memory _lastPoint = userPointHistory[_user][_epoch];\n        _lastPoint.bias =\n            _lastPoint.bias -\n            (_lastPoint.slope * SafeCast.toInt128(int256(_timestamp - _lastPoint.timestamp)));\n        if (_lastPoint.bias < 0) {\n            _lastPoint.bias = 0;\n        }\n        return SafeCast.toUint256(_lastPoint.bias);\n    }\n\n    /// @notice Record global and per-user slope to checkpoint\n    /// @param _address User's wallet address. Only global if 0x0\n    /// @param _prevLocked User's previous locked balance and end lock time\n    /// @param _newLocked User's new locked balance and end lock time\n    function _checkpoint(\n        address _address,\n        LockedBalance memory _prevLocked,\n        LockedBalance memory _newLocked\n    ) internal {\n        Point memory _userPrevPoint = Point({slope: 0, bias: 0, timestamp: 0, blockNumber: 0});\n        Point memory _userNewPoint = Point({slope: 0, bias: 0, timestamp: 0, blockNumber: 0});\n\n        int128 _prevSlopeDelta = 0;\n        int128 _newSlopeDelta = 0;\n        uint256 _epoch = epoch;\n\n        // if not 0x0, then update user's point\n        if (_address != address(0)) {\n            // Calculate slopes and biases according to linear decay graph\n            // slope = lockedAmount / MAX_LOCK => Get the slope of a linear decay graph\n            // bias = slope * (lockedEnd - currentTimestamp) => Get the voting weight at a given time\n            // Kept at zero when they have to\n            if (_prevLocked.end > block.timestamp && _prevLocked.amount > 0) {\n                // Calculate slope and bias for the prev point\n                _userPrevPoint.slope = _prevLocked.amount / SafeCast.toInt128(int256(MAX_LOCK));\n                _userPrevPoint.bias =\n                    _userPrevPoint.slope *\n                    SafeCast.toInt128(int256(_prevLocked.end - block.timestamp));\n            }\n            if (_newLocked.end > block.timestamp && _newLocked.amount > 0) {\n                // Calculate slope and bias for the new point\n                _userNewPoint.slope = _newLocked.amount / SafeCast.toInt128(int256(MAX_LOCK));\n                _userNewPoint.bias = _userNewPoint.slope * SafeCast.toInt128(int256(_newLocked.end - block.timestamp));\n            }\n\n            // Handle user history here\n            // Do it here to prevent stack overflow\n            uint256 _userEpoch = userPointEpoch[_address];\n            // If user never ever has any point history, push it here for him.\n            if (_userEpoch == 0) {\n                userPointHistory[_address].push(_userPrevPoint);\n            }\n\n            // Shift user's epoch by 1 as we are writing a new point for a user\n            userPointEpoch[_address] = _userEpoch + 1;\n\n            // Update timestamp & block number then push new point to user's history\n            _userNewPoint.timestamp = block.timestamp;\n            _userNewPoint.blockNumber = block.number;\n            userPointHistory[_address].push(_userNewPoint);\n\n            // Read values of scheduled changes in the slope\n            // _prevLocked.end can be in the past and in the future\n            // _newLocked.end can ONLY be in the FUTURE unless everything expired (anything more than zeros)\n            _prevSlopeDelta = slopeChanges[_prevLocked.end];\n            if (_newLocked.end != 0) {\n                // Handle when _newLocked.end != 0\n                if (_newLocked.end == _prevLocked.end) {\n                    // This will happen when user adjust lock but end remains the same\n                    // Possibly when user deposited more Cake to his locker\n                    _newSlopeDelta = _prevSlopeDelta;\n                } else {\n                    // This will happen when user increase lock\n                    _newSlopeDelta = slopeChanges[_newLocked.end];\n                }\n            }\n        }\n\n        // Handle global states here\n        Point memory _lastPoint = Point({bias: 0, slope: 0, timestamp: block.timestamp, blockNumber: block.number});\n        if (_epoch > 0) {\n            // If _epoch > 0, then there is some history written\n            // Hence, _lastPoint should be pointHistory[_epoch]\n            // else _lastPoint should an empty point\n            _lastPoint = pointHistory[_epoch];\n        }\n        // _lastCheckpoint => timestamp of the latest point\n        // if no history, _lastCheckpoint should be block.timestamp\n        // else _lastCheckpoint should be the timestamp of latest pointHistory\n        uint256 _lastCheckpoint = _lastPoint.timestamp;\n\n        // initialLastPoint is used for extrapolation to calculate block number\n        // (approximately, for xxxAt methods) and save them\n        // as we cannot figure that out exactly from inside contract\n        Point memory _initialLastPoint = Point({\n            bias: 0,\n            slope: 0,\n            timestamp: _lastPoint.timestamp,\n            blockNumber: _lastPoint.blockNumber\n        });\n\n        // If last point is already recorded in this block, _blockSlope=0\n        // That is ok because we know the block in such case\n        uint256 _blockSlope = 0;\n        if (block.timestamp > _lastPoint.timestamp) {\n            // Recalculate _blockSlope if _lastPoint.timestamp < block.timestamp\n            // Possiblity when epoch = 0 or _blockSlope hasn't get updated in this block\n            _blockSlope =\n                (MULTIPLIER * (block.number - _lastPoint.blockNumber)) /\n                (block.timestamp - _lastPoint.timestamp);\n        }\n\n        // Go over weeks to fill history and calculate what the current point is\n        uint256 _weekCursor = _timestampToFloorWeek(_lastCheckpoint);\n        for (uint256 i = 0; i < 255; i++) {\n            // This logic will works for 5 years, if more than that vote power will be broken 😟\n            // Bump _weekCursor a week\n            _weekCursor = _weekCursor + WEEK;\n            int128 _slopeDelta = 0;\n            if (_weekCursor > block.timestamp) {\n                // If the given _weekCursor go beyond block.timestamp,\n                // We take block.timestamp as the cursor\n                _weekCursor = block.timestamp;\n            } else {\n                // If the given _weekCursor is behind block.timestamp\n                // We take _slopeDelta from the recorded slopeChanges\n                // We can use _weekCursor directly because key of slopeChanges is timestamp round off to week\n                _slopeDelta = slopeChanges[_weekCursor];\n            }\n\n            // Calculate _biasDelta = _lastPoint.slope * (_weekCursor - _lastCheckpoint)\n            int128 _biasDelta = _lastPoint.slope * SafeCast.toInt128(int256((_weekCursor - _lastCheckpoint)));\n            _lastPoint.bias = _lastPoint.bias - _biasDelta;\n            _lastPoint.slope = _lastPoint.slope + _slopeDelta;\n            if (_lastPoint.bias < 0) {\n                // This can happen\n                _lastPoint.bias = 0;\n            }\n            if (_lastPoint.slope < 0) {\n                // This cannot happen, just make sure\n                _lastPoint.slope = 0;\n            }\n            // Update _lastPoint to the new one\n            _lastCheckpoint = _weekCursor;\n            _lastPoint.timestamp = _weekCursor;\n            // As we cannot figure that out block timestamp -> block number exactly\n            // when query states from xxxAt methods, we need to calculate block number\n            // based on _initalLastPoint\n            _lastPoint.blockNumber =\n                _initialLastPoint.blockNumber +\n                ((_blockSlope * ((_weekCursor - _initialLastPoint.timestamp))) / MULTIPLIER);\n            _epoch = _epoch + 1;\n            if (_weekCursor == block.timestamp) {\n                // Hard to be happened, but better handling this case too\n                _lastPoint.blockNumber = block.number;\n                break;\n            } else {\n                pointHistory.push(_lastPoint);\n            }\n        }\n        // Now, each week pointHistory has been filled until current timestamp (round off by week)\n        // Update epoch to be the latest state\n        epoch = _epoch;\n\n        if (_address != address(0)) {\n            // If the last point was in the block, the slope change should have been applied already\n            // But in such case slope shall be 0\n            _lastPoint.slope = _lastPoint.slope + _userNewPoint.slope - _userPrevPoint.slope;\n            _lastPoint.bias = _lastPoint.bias + _userNewPoint.bias - _userPrevPoint.bias;\n            if (_lastPoint.slope < 0) {\n                _lastPoint.slope = 0;\n            }\n            if (_lastPoint.bias < 0) {\n                _lastPoint.bias = 0;\n            }\n        }\n\n        // Record the new point to pointHistory\n        // This would be the latest point for global epoch\n        pointHistory.push(_lastPoint);\n\n        if (_address != address(0)) {\n            // Schedule the slope changes (slope is going downward)\n            // We substract _newSlopeDelta from `_newLocked.end`\n            // and add _prevSlopeDelta to `_prevLocked.end`\n            if (_prevLocked.end > block.timestamp) {\n                // _prevSlopeDelta was <something> - _userPrevPoint.slope, so we offset that first\n                _prevSlopeDelta = _prevSlopeDelta + _userPrevPoint.slope;\n                if (_newLocked.end == _prevLocked.end) {\n                    // Handle the new deposit. Not increasing lock.\n                    _prevSlopeDelta = _prevSlopeDelta - _userNewPoint.slope;\n                }\n                slopeChanges[_prevLocked.end] = _prevSlopeDelta;\n            }\n            if (_newLocked.end > block.timestamp) {\n                if (_newLocked.end > _prevLocked.end) {\n                    // At this line, the old slope should gone\n                    _newSlopeDelta = _newSlopeDelta - _userNewPoint.slope;\n                    slopeChanges[_newLocked.end] = _newSlopeDelta;\n                }\n            }\n        }\n    }\n\n    /// @notice Trigger global checkpoint\n    function checkpoint() external {\n        LockedBalance memory empty = LockedBalance({amount: 0, end: 0});\n        _checkpoint(address(0), empty, empty);\n    }\n\n    /// @notice Migrate from cake pool.\n    function createLockFromCakePool(address _for, address _proxy, uint256 _amount, uint256 _end) external onlyReceiver nonReentrant {\n        require(_proxy != address(0), \"proxy address is empty\");\n        UserInfo storage user = userInfo[_for];\n        require(user.cakePoolType == 0, \"Already migrated\");\n\n        user.cakePoolType = MIGRATION_FROM_CAKE_POOL_FLAG;\n        isCakePoolProxy[_proxy] = true;\n        user.cakePoolProxy = _proxy;\n        user.migrationTime = uint48(block.timestamp);\n        user.cakeAmount = uint128(_amount);\n        user.lockEndTime = uint48(_end);\n\n        _createLock(_proxy, _amount, _end);\n\n        emit CreateLockFromCakePool(msg.sender, _proxy, _amount, _end);\n    }\n\n    /// @notice Update deposit `_amount` tokens for `_for` and add to `locks[_for]`\n    /// @dev This function is used for update deposit to exist lock or create new lock.\n    /// @param _for The address to do the update\n    /// @param _amount the amount that user wishes to deposit\n    /// @param _unlockTime the timestamp when Cake get unlocked, it will be\n    /// floored down to whole weeks\n    function createLock(address _for, uint256 _amount, uint256 _unlockTime) external onlyReceiver nonReentrant {\n        _createLock(_for, _amount, _unlockTime);\n    }\n\n    function _createLock(address _for, uint256 _amount, uint256 _unlockTime) internal {\n        _unlockTime = _timestampToFloorWeek(_unlockTime);\n        LockedBalance memory _locked = locks[_for];\n\n        require(_amount > 0, \"Bad _amount\");\n        require(_locked.amount == 0, \"Already locked\");\n        require(_unlockTime > block.timestamp, \"_unlockTime too old\");\n        require(_unlockTime <= block.timestamp + MAX_LOCK, \"_unlockTime too long\");\n\n        _depositFor(_for, _amount, _unlockTime, _locked, ACTION_CREATE_LOCK);\n    }\n\n    /// @notice Internal function to perform deposit and lock Cake for a user\n    /// @param _for The address to be locked and received VECake\n    /// @param _amount The amount to deposit\n    /// @param _unlockTime New time to unlock Cake. Pass 0 if no change.\n    /// @param _prevLocked Existed locks[_for]\n    /// @param _actionType The action that user did as this internal function shared among\n    /// several external functions\n    function _depositFor(\n        address _for,\n        uint256 _amount,\n        uint256 _unlockTime,\n        LockedBalance memory _prevLocked,\n        uint256 _actionType\n    ) internal {\n        // Store _prevLocked\n        LockedBalance memory _newLocked = LockedBalance({amount: _prevLocked.amount, end: _prevLocked.end});\n\n        // Adding new lock to existing lock, or if lock is expired\n        // - creating a new one\n        _newLocked.amount = _newLocked.amount + SafeCast.toInt128(int256(_amount));\n        if (_unlockTime != 0) {\n            _newLocked.end = _unlockTime;\n        }\n\n        locks[_for] = _newLocked;\n\n        // Handling checkpoint here\n        _checkpoint(_for, _prevLocked, _newLocked);\n\n        emit Deposit(_for, _amount, _newLocked.end, _actionType, block.timestamp);\n    }\n\n    /// @notice Do Binary Search to find out block timestamp for block number\n    /// @param _blockNumber The block number to find timestamp\n    /// @param _maxEpoch No beyond this timestamp\n    function _findBlockEpoch(uint256 _blockNumber, uint256 _maxEpoch) internal view returns (uint256) {\n        uint256 _min = 0;\n        uint256 _max = _maxEpoch;\n        // Loop for 128 times -> enough for 128-bit numbers\n        for (uint256 i = 0; i < 128; i++) {\n            if (_min >= _max) {\n                break;\n            }\n            uint256 _mid = (_min + _max + 1) / 2;\n            if (pointHistory[_mid].blockNumber <= _blockNumber) {\n                _min = _mid;\n            } else {\n                _max = _mid - 1;\n            }\n        }\n        return _min;\n    }\n\n    /// @notice Do Binary Search to find the most recent user point history preceeding block\n    /// @param _user The address of user to find\n    /// @param _blockNumber Find the most recent point history before this block number\n    function _findUserBlockEpoch(address _user, uint256 _blockNumber) internal view returns (uint256) {\n        uint256 _min = 0;\n        uint256 _max = userPointEpoch[_user];\n        for (uint256 i = 0; i < 128; i++) {\n            if (_min >= _max) {\n                break;\n            }\n            uint256 _mid = (_min + _max + 1) / 2;\n            if (userPointHistory[_user][_mid].blockNumber <= _blockNumber) {\n                _min = _mid;\n            } else {\n                _max = _mid - 1;\n            }\n        }\n        return _min;\n    }\n\n    /// @notice Increase lock amount without increase \"end\"\n    /// @param _for The address to increase\n    /// @param _amount The amount of Cake to be added to the lock\n    function increaseLockAmount(address _for, uint256 _amount) external onlyReceiver nonReentrant {\n        LockedBalance memory _lock = LockedBalance({amount: locks[_for].amount, end: locks[_for].end});\n\n        require(_amount > 0, \"Bad _amount\");\n        require(_lock.amount > 0, \"No lock found\");\n        require(_lock.end > block.timestamp, \"Lock expired\");\n\n        _depositFor(_for, _amount, 0, _lock, ACTION_INCREASE_LOCK_AMOUNT);\n    }\n\n    /// @notice Increase unlock time without changing locked amount\n    /// @param _for The address to increase\n    /// @param _newUnlockTime The new unlock time to be updated\n    function increaseUnlockTime(address _for, uint256 _newUnlockTime) external onlyReceiver nonReentrant {\n        LockedBalance memory _lock = LockedBalance({amount: locks[_for].amount, end: locks[_for].end});\n        _newUnlockTime = _timestampToFloorWeek(_newUnlockTime);\n\n        require(_lock.amount > 0, \"No lock found\");\n        require(_lock.end > block.timestamp, \"Lock expired\");\n        require(_newUnlockTime > _lock.end, \"_newUnlockTime too old\");\n        require(_newUnlockTime <= block.timestamp + MAX_LOCK, \"_newUnlockTime too long\");\n\n        _depositFor(_for, 0, _newUnlockTime, _lock, ACTION_INCREASE_UNLOCK_TIME);\n    }\n\n    /// @notice Round off random timestamp to week\n    /// @param _timestamp The timestamp to be rounded off\n    function _timestampToFloorWeek(uint256 _timestamp) internal pure returns (uint256) {\n        return (_timestamp / WEEK) * WEEK;\n    }\n\n    /// @notice Withdraw all Cake when lock has expired.\n    /// @param _for The address to withdraw\n    /// @param _to The address which will receive the cake\n    function withdrawAll(address _for, address _to) external onlyReceiver nonReentrant {\n        LockedBalance memory _lock = locks[_for];\n\n        if (_to == address(0)) {\n            _to = _for;\n        }\n\n        uint256 _amount = SafeCast.toUint256(_lock.amount);\n\n        _unlock(_for, _lock, _amount);\n\n        emit WithdrawAll(_for, _to, _amount, block.timestamp);\n    }\n\n    function _unlock(\n        address _user,\n        LockedBalance memory _lock,\n        uint256 _withdrawAmount\n    ) internal {\n        // Cast here for readability\n        uint256 _lockedAmount = SafeCast.toUint256(_lock.amount);\n        require(_withdrawAmount <= _lockedAmount, \"Amount too large\");\n\n        LockedBalance memory _prevLock = LockedBalance({end: _lock.end, amount: _lock.amount});\n        //_lock.end should remain the same if we do partially withdraw\n        _lock.end = _lockedAmount == _withdrawAmount ? 0 : _lock.end;\n        _lock.amount = SafeCast.toInt128(int256(_lockedAmount - _withdrawAmount));\n        locks[_user] = _lock;\n\n        // _prevLock can have either block.timstamp >= _lock.end or zero end\n        // _lock has only 0 end\n        // Both can have >= 0 amount\n        _checkpoint(_user, _prevLock, _lock);\n    }\n\n\n    /// @dev Update receiver address in this contract, this is called by owner only\n    /// @param _receiver the address of new receiver\n    function updateReceiver(address _receiver) external onlyOwner {\n        require(receiver != _receiver, \"receiver not change\");\n        receiver = _receiver;\n    }\n    \n    /// @notice Update deposit `_amount` tokens for `_for` and add to `locks[_for]`\n    /// @dev This function is used for update total supply.\n    /// @param _supply The supply for total\n    function updateTotalSupply(uint256 _supply) external nonReentrant onlyReceiver {\n        uint256 previousSupply = supply;\n        supply = _supply;\n        emit Supply(previousSupply, _supply);\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 1
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}