Solidity 闪电贷合同存在问题

问题描述 投票:0回答:1

所以我正在使用 Aave 的闪贷协议,但我无法解决这个问题。如果我输入的金额是 100,合约只会允许我接受闪电贷,无论什么资产,而且不精确到任何小数位。我输入高于 100 的任何值,合约就会恢复。任何帮助都会很棒。

    // SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.10;

import {FlashLoanSimpleReceiverBase} from "@aave/core-v3/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol";
import {IPoolAddressesProvider} from "@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol";
import {IERC20} from "@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol";


contract FlashLoan is FlashLoanSimpleReceiverBase {
    address payable owner;
    address immutable debtUSDC = 0xFCCf3cAbbe80101232d343252614b6A3eE81C989;
    address immutable collUSDC = 0x625E7708f30cA75bfd92586e17077590C60eb4cD;
    


    constructor(address _addressProvider)
            FlashLoanSimpleReceiverBase(IPoolAddressesProvider(_addressProvider)) {
            owner = payable(msg.sender);            
        }

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

        // This is the body of the contract, the borrowed funds are here,
        // This is where the loan logic goes
        function executeOperation(
            address asset, // Asset to borrow
            uint256 amount, // Amount to borrow
            uint256 premium, // Fee for loan
            address  initiator, // Address of the flashloan initiator
            bytes calldata params //Byte incoded perameters passed when initiation the flashlaon
        ) external override returns (bool) {

            emit paramCheck (asset, amount, premium, address(POOL), params);

            uint256 amountOwed = amount + premium;
            uint256 interestRateMode = 2;
            uint16 referralCode = 0;

            approve(address(POOL), asset, (amountOwed + (amountOwed * 5 /100)));

            emit loanReceived (amountOwed);

            //POOL.repay(asset, IERC20(debtUSDC).balanceOf(address(owner)), interestRateMode, owner);
            //POOL.withdraw(asset, (IERC20(collUSDC).balanceOf(owner) * 90 / 100), initiator);

            // This determins if theres enough funds in contract holdings to pay back loan
            // If not, it checks the owners assets for remaining funds, if funds are unavailibe 
            // it borrows from aave supply to cover the differance
            if (getBalance(initiator, asset) <= amountOwed) {
                uint256 amountRequired = amountOwed - getBalance(initiator, asset);
                
                approve(owner, asset, (amountRequired + ((amountRequired + 1) * 15 / 100)));

                emit fundCheck (amountOwed, getBalance(initiator, asset), getBalance(owner, asset), 1);
                emit allowanceCheck (allowance(owner, initiator, asset));

                if (allowance(owner, initiator, asset) <= amountRequired && getBalance(initiator, asset) < amountOwed) {
                    POOL.borrow(asset, amountRequired, interestRateMode, referralCode, owner);
                    emit borrow (amountRequired, getBalance(initiator, asset));

                    return true;

                }  else if (allowance(owner, initiator, asset) > amountRequired) {
                    transfer(owner, initiator, asset, (amountRequired + ((amountRequired + 1) * 15 / 100)));
                    return true;
                }

            } else if (getBalance(initiator, asset) >= amountOwed) {
                return true;
            }

            emit allowanceCheck (allowance(address(POOL), initiator, asset));

            return true;
        }

        // This function initiates the flashloan with desired token and amount
        function requestFlashLoan(address _token, uint256 _amount) public {
            address receiverAddress = address(this); // Set to this contract
            address asset = _token;
            uint256 amount = _amount;
            bytes memory params = "";
            uint16 referralCode = 0;
            
            emit initCheck (receiverAddress, asset, amount, referralCode);

            POOL.flashLoanSimple(receiverAddress, asset, amount, params, referralCode);

        }

        function withdraw (address holder, address receiver, address asset, uint256 amount) external onlyOwner {
            IERC20(asset).transferFrom(holder, receiver, amount);
        }

        function getBalance(address holder, address asset) internal view returns (uint256) {
            return IERC20(asset).balanceOf(holder);
        }

        function allowance(address sender, address spender, address asset) internal view returns (uint256) {
            return IERC20(asset).allowance(sender, spender);
        }

        function transfer(address sender, address receiver, address asset, uint256 amount) internal returns (bool) {
            IERC20(asset).transferFrom(sender, receiver, amount);
            emit tokensTransferd (true);
            return true;
        }

        function approve(address holder, address asset, uint256 amount) internal returns (bool) {
            IERC20(asset).approve(holder, amount);
            emit tokenApproved (true);
            return true;
        }

        event loanReceived (
            uint256 loanValue
        );

        event fundCheck (
            uint256 loanValue,
            uint256 contractHoldings,
            uint256 ownerHoldings,
            uint256 step
        );

        event allowanceCheck (
            uint256 allowance
        );

        event borrow (
            uint256 loanValue,
            uint256 contractHoldings
        );

        event tokenApproved (
            bool approved
        );

        event tokensTransferd (
            bool transferSuccesfull
        );

        event paramCheck (
            address asset,
            uint256 amount,
            uint256 premium,
            address POOL,
            bytes params
        );

        event initCheck (
            address receiverAddress, 
            address asset, 
            uint256 amount, 
            uint16 referralCode
        );
        
        // Enables contract to receive payments
        receive() external payable {}

}
solidity
1个回答
0
投票

在请求闪电贷之前,我需要将资产代币从我的主地址转移到合约地址以支付闪电贷费用。如果闪电贷逻辑返回足够的利润来支付费用,这可能会得到纠正。

© www.soinside.com 2019 - 2024. All rights reserved.