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