我正在尝试存入Aave V2 Contract Aave代码示例
// SPDX-License-Identifier: MIT
pragma solidity >= 0.4.22 < 0.8.7;
import { IERC20, ILendingPool, IProtocolDataProvider, IStableDebtToken } from './Interfaces.sol';
import { SafeERC20 } from './Libraries.sol';
/**
* This is a proof of concept starter contract, showing how uncollaterised loans are possible
* using Aave v2 credit delegation.
* This example supports stable interest rate borrows.
* It is not production ready (!). User permissions and user accounting of loans should be implemented.
* See @dev comments
*/
contract MyV2CreditDelegation {
using SafeERC20 for IERC20;
ILendingPool constant lendingPool = ILendingPool(address(0x9FE532197ad76c5a68961439604C037EB79681F0)); // Kovan
IProtocolDataProvider constant dataProvider = IProtocolDataProvider(address(0x744C1aaA95232EeF8A9994C4E0b3a89659D9AB79)); // Kovan
address owner;
constructor () public {
owner = msg.sender;
}
/**
* Deposits collateral into the Aave, to enable credit delegation
* This would be called by the delegator.
* @param asset The asset to be deposited as collateral
* @param amount The amount to be deposited as collateral
* @param isPull Whether to pull the funds from the caller, or use funds sent to this contract
* User must have approved this contract to pull funds if `isPull` = true
*
*/
function depositCollateral(address asset, uint256 amount, bool isPull) public {
if (isPull) {
IERC20(asset).safeTransferFrom(msg.sender, address(this), amount);
}
IERC20(asset).safeApprove(address(lendingPool), amount);
lendingPool.deposit(asset, amount, address(this), 0);
}
/**
* Approves the borrower to take an uncollaterised loan
* @param borrower The borrower of the funds (i.e. delgatee)
* @param amount The amount the borrower is allowed to borrow (i.e. their line of credit)
* @param asset The asset they are allowed to borrow
*
* Add permissions to this call, e.g. only the owner should be able to approve borrowers!
*/
function approveBorrower(address borrower, uint256 amount, address asset) public {
(, address stableDebtTokenAddress,) = dataProvider.getReserveTokensAddresses(asset);
IStableDebtToken(stableDebtTokenAddress).approveDelegation(borrower, amount);
}
/**
* Repay an uncollaterised loan
* @param amount The amount to repay
* @param asset The asset to be repaid
*
* User calling this function must have approved this contract with an allowance to transfer the tokens
*
* You should keep internal accounting of borrowers, if your contract will have multiple borrowers
*/
function repayBorrower(uint256 amount, address asset) public {
IERC20(asset).safeTransferFrom(msg.sender, address(this), amount);
IERC20(asset).safeApprove(address(lendingPool), amount);
lendingPool.repay(asset, amount, 1, address(this));
}
/**
* Withdraw all of a collateral as the underlying asset, if no outstanding loans delegated
* @param asset The underlying asset to withdraw
*
* Add permissions to this call, e.g. only the owner should be able to withdraw the collateral!
*/
function withdrawCollateral(address asset) public {
(address aTokenAddress,,) = dataProvider.getReserveTokensAddresses(asset);
uint256 assetBalance = IERC20(aTokenAddress).balanceOf(address(this));
lendingPool.withdraw(asset, assetBalance, owner);
}
}我有这样的代码:
App = {
web3Provider: null,
contracts: {},
init: async function() {
return await App.initWeb3();
},
initWeb3: async function() {
// Modern dapp browsers...
if (window.ethereum) {
App.web3Provider = window.ethereum;
try {
// Request account access
await window.ethereum.enable();
} catch (error) {
// User denied account access...
console.error("User denied account access")
}
}
// Legacy dapp browsers...
else if (window.web3) {
App.web3Provider = window.web3.currentProvider;
}
// If no injected web3 instance is detected, fall back to Ganache
else {
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:8545');
}
web3 = new Web3(App.web3Provider);
return App.initContract();
},
initContract: function() {
$.getJSON('MyV2CreditDelegation.json', function(data) {
// Get the necessary contract artifact file and instantiate it with @truffle/contract
var safeYieldArtifact = data;
App.contracts.MyV2CreditDelegation = TruffleContract(safeYieldArtifact);
// Set the provider for our contract
App.contracts.MyV2CreditDelegation.setProvider(App.web3Provider);
});
return App.bindEvents();
},
bindEvents: function() {
$(document).on('click', '.btn-deposit', App.handleDeposit);
$(document).on('click', '.btn-withdrawl', App.handleWithdrawl);
},
handleDeposit: function(event) {
event.preventDefault();
web3.eth.getAccounts(function(error, accounts) {
if (error) {
console.log(error);
}
var account = accounts[0];
App.contracts.MyV2CreditDelegation.deployed().then(function(instance) {
creditDelegatorInstance = instance;
const mockETHAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
// Execute adopt as a transaction by sending account
return creditDelegatorInstance.depositCollateral(mockETHAddress, 1, true);
}).then(function(result) {
//return App.markAdopted();
}).catch(function(err) {
console.log(err.message);
});
});
},
handleWithdrawl: function(event) {
event.preventDefault();
},
};
$(function() {
$(window).load(function() {
App.init();
});
});当尝试提供时,Metamask会显示一个错误:
警报:事务错误。在合同代码中引发的异常。
只需一个简单的按钮就可以在html中调用它:
<button class="btn btn-default btn-withdrawl"
type="button"> Withdrawl
</button>我在跑步
ganache-cli --fork https://mainnet.infura.io/v3/{{MyProjectId}}
我在控制台中看到的唯一错误是:
事务处理: 0x9961f8a187c09fd7c9ebf803771fa161c9939268bb01552a1598807bcfdc13ff气体使用: 24813块号: 12905002块时间: Mon 71.262021 20:38:30格林尼治时间-0400(东部夏令时)运行时错误:恢复
我的猜测是,我并没有恰当地调用Web3的合同
如何以编程方式向aave提供Eth (或任何其他令牌)?
发布于 2021-08-08 20:15:12
我在浏览器中使用了硬帽子来发送事务,而不是Web3,但是我成功了:
创建一个新的HardHat项目
npm init --yes
npm install --save-dev hardhat
npm install @nomiclabs/hardhat-waffle
npm install --save-dev "@nomiclabs/hardhat-ethers@^2.0.0" "ethers@^5.0.0" "ethereum-waffle@^3.2.0"
npx hardhat
(follow the prompt)import '@nomiclabs/hardhat-ethers';
import * as dotenv from 'dotenv';
import { LogDescription } from 'ethers/lib/utils';
import hre from 'hardhat';
import { IERC20__factory, MyV2CreditDelegation__factory } from '../typechain';
dotenv.config();
// Infura, Alchemy, ... however you can get access to the Kovan test network
// E.g. https://kovan.infura.io/v3/<project-id>
const KOVAN_JSON_RPC = process.env.KOVAN_JSON_RPC || '';
if (!KOVAN_JSON_RPC) {
console.error('Forgot to set KOVAN_JSON_RPC in aave.ts or .env');
process.exit(1);
}
// Test account that has Kovan ETH and an AAVE token balance
const AAVE_HOLDER = '';
async function main() {
// Fork Kovan
await hre.network.provider.request({
method: 'hardhat_reset',
params: [{ forking: { jsonRpcUrl: KOVAN_JSON_RPC } }],
});
// Act like AAVE_HOLDER
await hre.network.provider.request({
method: 'hardhat_impersonateAccount',
params: [AAVE_HOLDER],
});
const signer = await hre.ethers.getSigner(AAVE_HOLDER);
console.log('signer:', signer.address);
// AAVE token on Kovan network
const token = IERC20__factory.connect('0xb597cd8d3217ea6477232f9217fa70837ff667af', signer);
console.log('token balance:', (await token.balanceOf(signer.address)).toString());
const MyV2CreditDelegation = new MyV2CreditDelegation__factory(signer);
const delegation = await MyV2CreditDelegation.deploy({ gasLimit: 1e7 });
console.log('delegation:', delegation.address);
await token.approve(delegation.address, 1000000000000);
console.log('allowance:', (await token.allowance(signer.address, delegation.address, { gasLimit: 1e6 })).toString());
const depositTrans = await delegation.depositCollateral(token.address, 1000000000000, true, { gasLimit: 1e6 });
console.log('depositTrans:', depositTrans.hash);
const receipt = await depositTrans.wait();
for (const log of receipt.logs) {
const [name, desc] = parseLog(log) || [];
if (desc) {
const args = desc.eventFragment.inputs.map(({ name, type, indexed }, index) =>
`\n ${type}${indexed ? ' indexed' : ''} ${name}: ${desc.args[name]}`);
args.unshift(`\n contract ${name} ${log.address}`);
console.log('Event', log.logIndex, `${desc.name}(${args ? args.join(',') : ''})`);
} else {
console.log('Log', log.logIndex, JSON.stringify(log.topics, null, 4), JSON.stringify(log.data));
}
}
function parseLog(log: { address: string, topics: Array<string>, data: string }): [string, LogDescription] | undefined {
try { return ['', delegation.interface.parseLog(log)]; } catch (e) { }
try {
const desc = token.interface.parseLog(log);
return [log.address.toLowerCase() === token.address.toLowerCase() ? 'AAVE' : 'IERC20', desc];
} catch (e) { }
}
}
main().then(() => process.exit(0), error => {
console.error(JSON.stringify(error));
console.error(error);
});其结果是:
$ hardhat run --no-compile --network kovan .\scripts\Aave.ts
token balance: 999999000000000000
delegation: 0x2863E2a95Dc84C227B11CF1997e295E59ab15670
allowance: 1000000000000
depositTrans: 0x0a3d1a8bfbdfc0f403371f9936122d19bdc9f3539c34e3fb1b0a7896a398f923
Done in 57.11s.您可以在科万的以太扫描上验证它(第26666177、26666180和26666183块):
MyV2CreditDelegation (事务,合同)Approval事件和token.allowance返回正确的值0.000001 AAVE从我的地址转移到已部署的合同0.000001 aAAVE从我的地址转移到已部署的合同0.000001 AAVE从部署合同转移到aAAVE合同最初,我的脚本将首先部署一个测试令牌(并在它上给我一些余额),我会尝试将其作为抵押品存入,但是提供者以某种方式恢复了它,甚至没有在Kovan Etherscan上出现一个事务。因此,您的代码中的问题可能是mockETHAddress,而且您似乎并没有实际批准您的委托合同来提取指定的金额。
在这个储存库中有一个更复杂但可以随时运行的安装程序。它模拟一个帐户,有一个ETH和AAVE余额在科万。
发布于 2022-09-05 05:17:20
如果有人在寻找如何在稳固契约中与Aave V3集成,下面是一个示例。
下面是一个简单的智能契约,允许您向Aave提供ERC20令牌抵押品,并获取可变利率贷款。
以下是您可以测试智能契约的方法:
// contracts/AaveExample.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
pragma abicoder v2;
import "@aave-protocol/interfaces/IPool.sol";
import "@openzeppelin-contracts/token/ERC20/IERC20.sol";
contract Aave {
// Storage Variables
address public borrowTokenAddress = 0xDF1742fE5b0bFc12331D8EAec6b478DfDbD31464; // Goerli Aave DAI
address public supplyTokenAddress = 0xA2025B15a1757311bfD68cb14eaeFCc237AF5b43; // Goerli Aave USDC
address public aavePoolAddress = 0x368EedF3f56ad10b9bC57eed4Dac65B26Bb667f6; // Goerli Aave Pool Address
constructor() {}
function supply() public returns (bool) {
// 1. Set amountToDrain to the contract's supplyTokenAddress balance
uint amountToDrain = IERC20(supplyTokenAddress).balanceOf(address(this));
// 2. Approve Aave pool to access amountToDrain from this contract
IERC20(supplyTokenAddress).approve(aavePoolAddress, amountToDrain);
// 3. Supply amountToDrain to Aave pool
IPool(aavePoolAddress).supply(supplyTokenAddress, amountToDrain, address(this), 0);
return true;
}
function borrow() public returns (bool) {
// Borrow 0.3 DAI
IPool(aavePoolAddress).borrow(borrowTokenAddress, 0.3 ether, 2, 0, address(this));
return true;
}
}https://stackoverflow.com/questions/68552918
复制相似问题