I need help for TRC20 Smart contract

Hello community,
I'm new to creating smart contracts, I need help. I want to create a smart contract that functions like a flash loan. I want to lend out my tokens. I want to determine the duration of the loan in advance. After this time has elapsed, the borrowed token should automatically be returned to the sender without the recipient having to approve it. Thank you in advance

1 Like
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Interface für TRC20-Token
interface ITRC20 {
    function transfer(address recipient, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function decimals() external view returns (uint8);
}

contract ManualRefund {
    address public owner;

    struct RefundableTransfer {
        address tokenAddress;
        address from;
        address to;
        uint256 amount;
        bool refunded;
    }

    RefundableTransfer[] public transfers;

    event TransferInitiated(address indexed tokenAddress, address indexed from, address indexed to, uint256 amount);
    event TransferRefunded(address indexed tokenAddress, address indexed from, address indexed to, uint256 amount);
    event TokensWithdrawn(address indexed tokenAddress, address indexed owner, uint256 amount);

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can call this function.");
        _;
    }

    constructor() {
        owner = msg.sender;
    }

    // Funktion zum Initiieren eines Transfers
    function initiateTransfer(
        address _tokenAddress,
        address _from,
        address _to,
        uint256 _amount
    ) external onlyOwner {
        ITRC20 token = ITRC20(_tokenAddress);

        // Überprüfen, ob der Absender genügend Guthaben hat
        require(token.balanceOf(_from) >= _amount, "Insufficient balance in sender's account.");

        // Überprüfen, ob der Absender dem Contract genügend Token genehmigt hat
        require(token.allowance(_from, address(this)) >= _amount, "Insufficient allowance for the contract.");

        // Token vom Absender zum Contract transferieren
        require(token.transferFrom(_from, address(this), _amount), "Transfer to contract failed.");

        // Transfer im Array speichern
        transfers.push(RefundableTransfer({
            tokenAddress: _tokenAddress,
            from: _from,
            to: _to,
            amount: _amount,
            refunded: false
        }));

        // Event auslösen
        emit TransferInitiated(_tokenAddress, _from, _to, _amount);
    }

    // Funktion zur Rückerstattung durch den ursprünglichen Absender
    function refundTransfer(uint256 _transferIndex) external {
        require(_transferIndex < transfers.length, "Invalid transfer index.");
        RefundableTransfer storage transfer = transfers[_transferIndex];
        require(msg.sender == transfer.from, "Only the original sender can refund.");
        require(!transfer.refunded, "Transfer already refunded.");

        ITRC20 token = ITRC20(transfer.tokenAddress);
        uint256 contractBalance = token.balanceOf(address(this));
        require(contractBalance >= transfer.amount, "Contract does not have enough tokens.");

        require(token.transfer(transfer.from, transfer.amount), "Refund transfer failed.");
        transfer.refunded = true;
        emit TransferRefunded(transfer.tokenAddress, transfer.from, transfer.to, transfer.amount);
    }

    // Funktion zur Freigabe der Token an den Empfänger
    function releaseFunds(uint256 _transferIndex) external onlyOwner {
        require(_transferIndex < transfers.length, "Invalid transfer index.");
        RefundableTransfer storage transfer = transfers[_transferIndex];
        require(!transfer.refunded, "Transfer already refunded.");

        ITRC20 token = ITRC20(transfer.tokenAddress);
        uint256 contractBalance = token.balanceOf(address(this));
        require(contractBalance >= transfer.amount, "Contract does not have enough tokens.");

        require(token.transfer(transfer.to, transfer.amount), "Release transfer failed.");
    }

    // Funktion zur Überprüfung, ob ein Transfer zurückerstattet werden kann
    function canRefund(uint256 _transferIndex) external view returns (bool) {
        require(_transferIndex < transfers.length, "Invalid transfer index.");
        RefundableTransfer storage transfer = transfers[_transferIndex];
        return (!transfer.refunded);
    }

    // Funktion zur Rückgabe der Anzahl der Transfers
    function getTransferCount() external view returns (uint256) {
        return transfers.length;
    }

    // Notfall-Funktion zum Abheben von verbleibenden Token
    function withdrawTokens(address _tokenAddress, uint256 _amount) external onlyOwner {
        ITRC20 token = ITRC20(_tokenAddress);
        require(token.balanceOf(address(this)) >= _amount, "Not enough tokens in contract.");
        require(token.transfer(owner, _amount), "Withdrawal failed.");

        emit TokensWithdrawn(_tokenAddress, owner, _amount);
    }
}

Hi, welcome to the community! :wave:

So what is wrong with your function like flash loan?

still looking for developer, if so, share the issues and problems you are facing.

Thanks.

get this error message "transact to TokenLending.lendTokens errored: SafeMath: subtraction overflow
" with this code,

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Interface für TRC20-Token
interface ITRC20 {
    function transfer(address recipient, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
}

contract TokenLending {
    struct Loan {
        address tokenAddress;
        address borrower;
        uint256 amount;
        uint256 returnTime;
        bool returned; // Flag, um zu überprüfen, ob die Tokens zurückgegeben wurden
    }

    mapping(uint256 => Loan) public loans;
    uint256 public loanCount;

    event LoanCreated(uint256 indexed loanId, address indexed tokenAddress, address indexed borrower, uint256 amount, uint256 returnTime);
    event LoanReturned(uint256 indexed loanId, address indexed tokenAddress, address indexed borrower, uint256 amount);

    // Funktion zum Verleihen von Token
    function lendTokens(
        address _tokenAddress,
        address _borrower,
        uint256 _amount,
        uint256 _durationInSeconds
    ) external {
        require(_durationInSeconds > 0, "Duration must be greater than zero.");
        
        ITRC20 token = ITRC20(_tokenAddress);
        
        // Überprüfen, ob der Contract genügend Token hat
        require(token.balanceOf(msg.sender) >= _amount, "Insufficient balance to lend.");

        // Token an den Borrower senden
        require(token.transfer(_borrower, _amount), "Transfer failed.");

        // Loan-Daten speichern
        loans[loanCount] = Loan({
            tokenAddress: _tokenAddress,
            borrower: _borrower,
            amount: _amount,
            returnTime: block.timestamp + _durationInSeconds,
            returned: false
        });

        emit LoanCreated(loanCount, _tokenAddress, _borrower, _amount, block.timestamp + _durationInSeconds);
        loanCount++;
    }

    // Funktion zur Rückgabe der Token nach Ablauf der Zeit
    function returnTokens(uint256 _loanId) external {
        Loan storage loan = loans[_loanId];

        require(msg.sender == loan.borrower, "Only the borrower can return the tokens.");
        require(block.timestamp >= loan.returnTime, "The loan period has not yet expired.");
        require(!loan.returned, "Tokens have already been returned."); // Überprüfen, ob die Tokens bereits zurückgegeben wurden

        ITRC20 token = ITRC20(loan.tokenAddress);
        
        // Token zurück an den Lender senden
        require(token.balanceOf(loan.borrower) >= loan.amount, "Insufficient balance to return the tokens.");
        
        // Tokens zurückgeben
        require(token.transfer(msg.sender, loan.amount), "Return transfer failed.");

        emit LoanReturned(_loanId, loan.tokenAddress, loan.borrower, loan.amount);
        
        // Loan-Daten löschen
        loan.returned = true; // Setze den Rückgabestatus
    }
}

I test this code in nile testnet with these values,
tokenAddress: xxxx
_borrower: xxxx
_amount: 99
_durationInSeconds: 300

Maybe you should check the balance of the contract rather than msg.sender in the lendTokens function.

require(token.balanceOf(address(this)) >= _amount, "Insufficient balance to lend.");