Разве при развертывании смарт-контракта «владелец» контракта (по умолчанию) не тот, кто его развертывает?
Я пытаюсь использовать функцию в контракте flashloan, в которой используется модификатор onlyOwner. Когда я отправляю транзакцию flashloan, мне возвращается ошибка: «вызывающий абонент не является владельцем».
Я использую ту же учетную запись, которую использовал для создания контракта при запуске этой быстрой ссуды, поэтому я не уверен, почему она не распознает меня как владельца.
Вы можете видеть, что это один и тот же адрес для создания контракта и для отправки неудавшейся транзакции. https://kovan.etherscan.io/address/0x91109bde85e0ab631d1983ce07b910ce4e99078a
Нажмите на первую транзакцию ^^, чтобы увидеть сообщение об ошибке.
код модификатора onlyOwner: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol
Файл контракта
pragma solidity ^0.6.6;
import "./aave/FlashLoanReceiverBaseV2.sol";
import "../../interfaces/v2/ILendingPoolAddressesProviderV2.sol";
import "../../interfaces/v2/ILendingPoolV2.sol";
contract FlashloanV2 is FlashLoanReceiverBaseV2, Withdrawable {
constructor(address _addressProvider) FlashLoanReceiverBaseV2(_addressProvider) public {}
/**
* @dev This function must be called only be the LENDING_POOL and takes care of repaying
* active debt positions, migrating collateral and incurring new V2 debt token debt.
*
* @param assets The array of flash loaned assets used to repay debts.
* @param amounts The array of flash loaned asset amounts used to repay debts.
* @param premiums The array of premiums incurred as additional debts.
* @param initiator The address that initiated the flash loan, unused.
* @param params The byte array containing, in this case, the arrays of aTokens and aTokenAmounts.
*/
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
)
external
override
returns (bool)
{
//
// This contract now has the funds requested.
// Your logic goes here.
//
// At the end of your logic above, this contract owes
// the flashloaned amounts + premiums.
// Therefore ensure your contract has enough to repay
// these amounts.
// Approve the LendingPool contract allowance to *pull* the owed amount
for (uint i = 0; i < assets.length; i++) {
uint amountOwing = amounts[i].add(premiums[i]);
IERC20(assets[i]).approve(address(LENDING_POOL), amountOwing);
}
for (uint i = 0; i < assets.length; i++) {
withdraw(assets[i]);
}
return true;
}
function _flashloan(address[] memory assets, uint256[] memory amounts) internal {
address receiverAddress = address(this);
address onBehalfOf = address(this);
bytes memory params = "";
uint16 referralCode = 0;
uint256[] memory modes = new uint256[](assets.length);
// 0 = no debt (flash), 1 = stable, 2 = variable
for (uint256 i = 0; i < assets.length; i++) {
modes[i] = 0;
}
LENDING_POOL.flashLoan(
receiverAddress,
assets,
amounts,
modes,
onBehalfOf,
params,
referralCode
);
}
/*
* Flash multiple assets
*/
function flashloan(address[] memory assets, uint256[] memory amounts) public onlyOwner {
_flashloan(assets, amounts);
}
/*
* Flash loan 1000000000000000000 wei (1 ether) worth of `_asset`
*/
function flashloan(address _asset) public onlyOwner {
bytes memory data = "";
uint amount = 1 ether;
address[] memory assets = new address[](1);
assets[0] = _asset;
uint256[] memory amounts = new uint256[](1);
amounts[0] = amount;
_flashloan(assets, amounts);
}
}
Withdrawable.sol (откуда берется функция takew ())
pragma solidity ^0.6.6;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
Ensures that any contract that inherits from this contract is able to
withdraw funds that are accidentally received or stuck.
*/
contract Withdrawable is Ownable {
using SafeERC20 for ERC20;
address constant ETHER = address(0);
event LogWithdraw(
address indexed _from,
address indexed _assetAddress,
uint amount
);
/**
* @dev Withdraw asset.
* @param _assetAddress Asset to be withdrawn.
*/
function withdraw(address _assetAddress) public onlyOwner {
uint assetBalance;
if (_assetAddress == ETHER) {
address self = address(this); // workaround for a possible solidity bug
assetBalance = self.balance;
msg.sender.transfer(assetBalance);
} else {
assetBalance = ERC20(_assetAddress).balanceOf(address(this));
ERC20(_assetAddress).safeTransfer(msg.sender, assetBalance);
}
emit LogWithdraw(msg.sender, _assetAddress, assetBalance);
}
}