Smart Contracts BCD Assignment

mail@pastecode.io avatar
unknown
plain_text
a month ago
8.6 kB
9
Indexable
Never
CryptoLendsToken.sol:

// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";

contract CryptoLendsToken is ERC20, Ownable, Pausable {
    struct Loan {
        uint id;
        address payable borrower;
        address payable lender;
        uint amount;
        uint interest;
        uint duration;
        bool repaid;
    }

    uint public nextLoanId;
    mapping(uint => Loan) public loans;

    constructor(address initialOwner) ERC20("CryptoLendsToken", "CLT") Ownable(initialOwner) {
        _mint(initialOwner, 1000000 * 10 ** decimals());  // Mint initial tokens to owner
    }

    // Mint new tokens (Only owner can mint)
    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }

    // Pause all token transfers (Only owner can pause)
    function pause() public onlyOwner {
        _pause();
    }

    // Unpause all token transfers (Only owner can unpause)
    function unpause() public onlyOwner {
        _unpause();
    }

    // Request a loan
    function requestLoan(uint _amount, uint _interest, uint _duration) external {
        require(balanceOf(msg.sender) >= _amount, "Insufficient token balance for loan");
        loans[nextLoanId] = Loan({
            id: nextLoanId,
            borrower: payable(msg.sender),
            lender: payable(address(0)),
            amount: _amount,
            interest: _interest,
            duration: _duration,
            repaid: false
        });
        nextLoanId++;
    }

    // Fund a loan
    function fundLoan(uint _loanId) external payable whenNotPaused {
        Loan storage loan = loans[_loanId];
        require(msg.value == loan.amount, "Incorrect loan amount");
        require(loan.lender == address(0), "Loan already funded");
        loan.lender = payable(msg.sender);
        loan.borrower.transfer(msg.value);
    }

    // Repay a loan
    function repayLoan(uint _loanId) external payable whenNotPaused {
        Loan storage loan = loans[_loanId];
        require(msg.sender == loan.borrower, "Only borrower can repay");
        require(!loan.repaid, "Loan already repaid");
        require(msg.value == loan.amount + loan.interest, "Incorrect repayment amount");
        loan.lender.transfer(msg.value);
        loan.repaid = true;
    }

    // Buy tokens
    function buyToken() external payable whenNotPaused {
        require(msg.value > 0, "Need to send ETH to buy tokens");
        uint256 tokens = msg.value * 100; // Example conversion rate: 1 ETH = 100 CLT
        _mint(msg.sender, tokens);
    }

    // Sell tokens
    function sellToken(uint256 amount) external whenNotPaused {
        require(balanceOf(msg.sender) >= amount, "Insufficient token balance to sell");
        uint256 ethAmount = amount / 100; // Example conversion rate: 100 CLT = 1 ETH
        _burn(msg.sender, amount);
        payable(msg.sender).transfer(ethAmount);
    }

    // Withdraw contract balance (Only owner can withdraw)
    function withdraw() external onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }
}


ICO.sol:

// SPDX-License-Identifier: GPL-3.0
// Compatible with OpenZeppelin Contracts ^5.0.0

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";

contract ICO is Pausable, Ownable {
    IERC20 public token;
    uint public basePrice = 1 ether; // Base price in wei
    uint public totalTokensSold;
    uint public salePhase = 1;

    mapping(uint => uint) public phasePriceMultiplier; // Phase-specific price multipliers
    mapping(uint => uint) public phaseCap; // Token caps for each phase

    event TokensPurchased(address indexed buyer, uint256 amount, uint256 cost);

    constructor(address _tokenAddress) Ownable(msg.sender) {
        token = IERC20(_tokenAddress);

        // Setting up sale phases with different multipliers and caps
        phasePriceMultiplier[1] = 100; // 1x base price
        phaseCap[1] = 10000 * 10 ** 18; // 10,000 tokens

        phasePriceMultiplier[2] = 150; // 1.5x base price
        phaseCap[2] = 30000 * 10 ** 18; // 30,000 tokens

        phasePriceMultiplier[3] = 200; // 2x base price
        phaseCap[3] = 60000 * 10 ** 18; // 60,000 tokens
    }

    function buyToken() external payable whenNotPaused {
        uint256 weiAmount = msg.value;
        require(weiAmount > 0, "Payment is required");

        uint256 currentPrice = basePrice * phasePriceMultiplier[salePhase] / 100;
        uint256 numberOfTokens = weiAmount * 10 ** 18 / currentPrice;

        require(token.balanceOf(owner()) >= numberOfTokens, "Insufficient tokens available for sale");
        require(totalTokensSold + numberOfTokens <= phaseCap[salePhase], "Phase token cap exceeded");

        token.transferFrom(owner(), msg.sender, numberOfTokens);
        totalTokensSold += numberOfTokens;

        // Move to the next phase if the cap is reached
        if (totalTokensSold >= phaseCap[salePhase] && salePhase < 3) {
            salePhase++;
        }

        emit TokensPurchased(msg.sender, numberOfTokens, weiAmount);
    }

    function pause() external onlyOwner {
        _pause();
    }

    function unpause() external onlyOwner {
        _unpause();
    }

    function withdrawal() external onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }

    function setPhase(uint _phase, uint _multiplier, uint _cap) external onlyOwner {
        phasePriceMultiplier[_phase] = _multiplier;
        phaseCap[_phase] = _cap;
    }

    function setBasePrice(uint _newBasePrice) external onlyOwner {
        basePrice = _newBasePrice;
    }
}

ICO.sol:

// SPDX-License-Identifier: GPL-3.0
// Compatible with OpenZeppelin Contracts ^5.0.0

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";

contract ICO is Pausable, Ownable {
    IERC20 public token;
    uint public basePrice = 1 ether; // Base price in wei
    uint public totalTokensSold;
    uint public salePhase = 1;

    mapping(uint => uint) public phasePriceMultiplier; // Phase-specific price multipliers
    mapping(uint => uint) public phaseCap; // Token caps for each phase

    event TokensPurchased(address indexed buyer, uint256 amount, uint256 cost);

    constructor(address _tokenAddress) Ownable(msg.sender) {
        token = IERC20(_tokenAddress);

        // Setting up sale phases with different multipliers and caps
        phasePriceMultiplier[1] = 100; // 1x base price
        phaseCap[1] = 10000 * 10 ** 18; // 10,000 tokens

        phasePriceMultiplier[2] = 150; // 1.5x base price
        phaseCap[2] = 30000 * 10 ** 18; // 30,000 tokens

        phasePriceMultiplier[3] = 200; // 2x base price
        phaseCap[3] = 60000 * 10 ** 18; // 60,000 tokens
    }

    function buyToken() external payable whenNotPaused {
        uint256 weiAmount = msg.value;
        require(weiAmount > 0, "Payment is required");

        uint256 currentPrice = basePrice * phasePriceMultiplier[salePhase] / 100;
        uint256 numberOfTokens = weiAmount * 10 ** 18 / currentPrice;

        require(token.balanceOf(owner()) >= numberOfTokens, "Insufficient tokens available for sale");
        require(totalTokensSold + numberOfTokens <= phaseCap[salePhase], "Phase token cap exceeded");

        token.transferFrom(owner(), msg.sender, numberOfTokens);
        totalTokensSold += numberOfTokens;

        // Move to the next phase if the cap is reached
        if (totalTokensSold >= phaseCap[salePhase] && salePhase < 3) {
            salePhase++;
        }

        emit TokensPurchased(msg.sender, numberOfTokens, weiAmount);
    }

    function pause() external onlyOwner {
        _pause();
    }

    function unpause() external onlyOwner {
        _unpause();
    }

    function withdrawal() external onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }

    function setPhase(uint _phase, uint _multiplier, uint _cap) external onlyOwner {
        phasePriceMultiplier[_phase] = _multiplier;
        phaseCap[_phase] = _cap;
    }

    function setBasePrice(uint _newBasePrice) external onlyOwner {
        basePrice = _newBasePrice;
    }
}



Need to create buy, sell, borrow, and lend for the smart contract. (ERC20 Token & ICO Contract)

Leave a Comment