Interaction with Aave V3 contract getUserAccountData - solidity

I'm trying to make a normal request to another contract from mine.
function getUserAccountData(address _miskin) internal view returns (AaveUserData memory) {
ILendingPool lendingPool = ILendingPool(aaveLendingPoolAddress);
(uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor) = lendingPool.getUserAccountData(_miskin);
return AaveUserData(totalCollateralETH, totalDebtETH, availableBorrowsETH, currentLiquidationThreshold, ltv, healthFactor);
}
This is pretty basic and on the line lendingPool.getUserAccountData(_miskin); I get an error: function returned an unexpected amount of data.
I don't understand why I have the correct contract address also.
This is my interface
interface ILendingPool {
function getUserAccountData(address user)
external
view
returns (
uint256 totalCollateralETH,
uint256 totalDebtETH,
uint256 availableBorrowsETH,
uint256 currentLiquidationThreshold,
uint256 ltv,
uint256 healthFactor
);
}
I someone have any idea what can I do I would love thank you.

A struct is decoded differently than the list of its arguments. In particular it has extra bytes at the beginning.
So your code is expecting a output like (uint256, ..., uint256) but getting a AaveUserData struct. I'm not sure how the output of your internal function getUserAccountData is used, but I guess you're reading it using the Aave ILendingPool interface, which doesn't return a AaveUserData struct.

It's a bit of a dum answer but I forked the wrong network so whe. I tried to call the address with the good polygon address I got an error. So the solution: Fork the good network.

Related

Native coin MATIC has a Contract Address on the Polygon Network?

I am currently developing a donation smart contract for the Polygon blockchain.
The donation contract should receive many types of coins like (MATIC, USDT, USDC, etc.).
I first made the donate function like the below:
function donate(address donor, address token, bool isNativeCoin, uint256 amount);
But later, I noticed that the Polygon network has MATIC address differently from other evm-based chains.
So I removed the isNativeCoin flag variable in the method params.
function donate(address donor, address token, uint256 amount);
But I don't know that is real MATIC address is and how Polygon is different from other chains.
Here is my research about Polygon MATIC and WMATIC address.
MATIC
https://mumbai.polygonscan.com/address/0x0000000000000000000000000000000000001010
https://polygonscan.com/address/0x0000000000000000000000000000000000001010
WMATIC
https://mumbai.polygonscan.com/address/0x9c3c9283d3e44854697cd22d3faa240cfb032889#code
https://polygonscan.com/address/0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270
If I import 0x0000000000000000000000000000000000001010 as a token in my metamask wallet, it shows the same balance with Native MATIC balance. It's so interesting.
Here is the full mockup code.
address MATIC_TOKEN = 0x0000000000000000000000000000000000001010;
DonationInfo[] donations;
function _safeTransferMatic(address to, uint256 amount) internal {
(bool success, ) = to.call{value: amount}("");
require(success, "MATIC_TRANSFER_FAILED");
}
function donate(address donor, address token, uint256 amount) {
donations.push(DonationInfo(donor, token, amount);
}
function sendDonation(uint256 donateIndex) {
if (donations[donateIndex].token == MATIC_TOKEN) {
_safeTransferMatic(charityPartner, donations[donateIndex].amount);
} else {
IERC20(donations[donateIndex].token).safeTransfer(charityPartner,donations[donateIndex].amount);
}
}
Is the above code correct or should I use isNativeCoin flag variable?
Could you explain the Polygon MATIC address?
0x0000000000000000000000000000000000001010 is a precompile that supports some EIP-20 functions, such as balanceOf(address), name(), symbol(), and decimals(). It does not support functions like transfer(address, uint256), approve(address, uint256), or transferFrom(address, address, uint256).
Basically, it's a special address that isn't a contract that supports some, but not all EIP-20 functions.

Ethereum lottery smart contract reverts due to insufficient funds. Where does my code consumes that much gas?

I am experimenting with solidity and I faced an issue for what I could not find a solution.
The program should let addresses buy ticket at a preset price, and the owner can start the "roll the dice" function which randomly selects the winner and transfer the funds to that address.
I beleive that this program would be easier with mapping instead of array, but getting experience with array was the main purpose of this program.
The error happens when the user calls buyTicket function. Based on the response I beleive the contract comsumes too much gas. Can someone tell me why it doesnt work? I appreciate any other helping comment regarding the rest of the code:)
Thanks in advance!
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Lottery {
constructor () {
owner = msg.sender;
}
address[] public Players;
address private owner;
uint public ticketPrice;
uint public price;
uint public nonce;
uint public variations;
address payable winner;
bool hasTicketAnswer;
event Winner(address _winner);
event PriceSet(uint _setPrice);
event TicketBought();
function setTicketPrice(uint _ticketPrice) public {
require(msg.sender == owner, "Only Owner...");
ticketPrice = _ticketPrice;
emit PriceSet(_ticketPrice);
}
function hasTicket(address _sender) private returns(bool) {
hasTicketAnswer = false;
for (uint i = 0; i < Players.length; i++) {
if (Players[i] == _sender) hasTicketAnswer = true;
}
return hasTicketAnswer;
}
function buyTicket() external payable {
require(ticketPrice > 0, "Price did not set, be patient...");
require(hasTicket(msg.sender) == false, "You cannot have two tickets...");
require(msg.sender.balance <= ticketPrice, "Insufficient funds...");
payable(address(this)).transfer(ticketPrice);
Players.push(address(msg.sender));
price += msg.value;
emit TicketBought();
}
function checkBalance() public view returns(uint) {
return address(this).balance;
}
function rollTheDice() public payable {
variations = Players.length;
winner = payable(Players[uint(keccak256(abi.encodePacked(msg.sender, nonce, block.timestamp))) % variations]);
winner.transfer(price);
emit Winner(winner);
}
receive () external payable {
}
}
Besides probably finding the problem, I've read some things that I'd like to comment on.
Your problem
The reason why you're getting the "Insufficient funds" error is because the condition is returning false. You're asking the msg.sender balance to be less than or equal (<=) to ticketPrice, when it should be more than or equal (>=).
Let's say Alice has a balance of 0.05 ETH and interacts with the contract whose ticket price is 0.001 ETH...
require(0.05 ETH <= 0.001 ETH) // Reverting...
Observations
I'm curious if you're intentionally coding the buyTicket function in that way. What it actually does is checking if the msg.sender has enough ETH to buy a ticket in its wallet, which doesn't mean that the user is effectively sending ETH in the transaction (the amount of wei sent in the transaction can be checked with msg.value, you can read more about it here).
My last observation is the payable(address(this)).transfer(ticketPrice) line of code, because it's not necessary to do so, once a payable function receives ETH, it is saved into the contract... In that line you're just making the Bob's contract to send ETH to the Bob's contract, which just wastes gas without reason
I hope I've helped with you and if I wasn't completely clear in any thing I've said don't doubt in asking me

Token balance check is not working in Solidity smart contract

here is my code snippet and i have no idea why its not working
function Testdeposit(address _assetAddress) public returns (uint256 status)
{
//IERC20 erc20 = IERC20(_assetAddress);
//erc20.transferFrom(senderAddress, address(this), _amount));
//uint256 amount = erc20.allowance(senderAddress, address(this));
uint256 amount = IERC20(_assetAddress).balanceOf(address(this));
return amount;
}
i am using a standard IERC20 interface. just it dsnt have an event to emit. i assume it to return me 0 if there is no balance but its gvng me erro. Transcation not going through.
Any suggestions??
It is not working because you may have not overridden the IERC20 functions. At least as they should. I would highly recommend using the ERC20 standard instead, just for how easy it is to implement.

How to withdraw all tokens form my bsc contract

I'm really really inexperienced with contracts and need your help. I created a contract with remix and sent some bnb to it. I want to retrieve it but I can't seem to make it happen.
pragma solidity ^0.8;
interface IERC20 {
function transfer(address _to, uint256 _amount) external returns (bool);
}
contract MyContract {
function withdrawToken(address _tokenContract, uint256 _amount) external {
IERC20 tokenContract = IERC20(_tokenContract);
// transfer the token from address of this contract
// to address of the user (executing the withdrawToken() function)
tokenContract.transfer(msg.sender, _amount);
}
}
This is the code that I'm using from another post but I don't understand it. Do I have to change the "_to" "and "_amount" with the numbers or do I just copy the code and compile it?
I'm really sorry but I have no idea what I did so I just want to take the tokens back.
Thanks
Sorry but you can't withdraw your bnb, bnb isn't a token, bnb is like the ether in ethereum, the native chain currency and the contract doesn't have a function to let you withdraw it, the only way is if you send wbnb, in that case you can look the address of the contract of the wbnb and call the function withdraw of the contract you made
As Jhonny said, BNB is not an actual token, and so your implemented logic won't work to withdraw BNB. But just for you to know, you could create a function which only allows withdrawing BNB (which is the native currency). It would be something like this:
function withdraw(uint _amount) external {
payable(msg.sender).transfer(_amount);
}
Hope you find this useful.

call to FundMe.getVersion errored: VM execution error. Reverted 0x

// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.9.0 ;
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
// getRoundData and latestRoundData should both raise "No data present"
// if they do not have data to report, instead of returning unset values
// which could be misinterpreted as actual reported values.
function getRoundData(uint80 _roundId)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
contract FundMe {
mapping (address => uint256) public addressTotalAmountFunded;
function fund() public payable {
addressTotalAmountFunded[msg.sender] += msg.value;
}
function getVersion() public view returns (uint256){
AggregatorV3Interface priceFeed = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);
return priceFeed.version();
}
}
Hi I am trying to understand why I get this error when I want to check the version
Any thoughts?
The 0x5f4e... address hardcoded in your getVersion() function doesn't hold any smart contract on the Kovan testnet (link). Even though it has a contract deployed on the mainnet, these environments are separated.
When there's no smart contract on the address, there's nothing to send a response to the internal call. Your code expects an uint256 response from the version() call, so that it can return it from the getVersion().
When it doesn't receive the expected response, it throws an exception, effectively reverting the "main" call.
Make sure the address of the data feed is for the Testnet you are using (most likely Kovan) and not for Mainnet.
I experienced the same problem. The problem was with the network selection. You're requesting the price info from a wallet address/contract on Rinkby network. I tried the wallet address on the Kovan network instead and that worked for me.
This is the Kovan address I used 0x9326BFA02ADD2366b30bacB125260Af641031331
It worked find a returned the ETH/USD Price info.
So basically you can solve it in 2 ways:
Go to your metamask and change your network to Rinkby and use the rinkby ETH/USD address in your functions or
Keep your network on Kovan and use the Kovan ETH/USD address.