Uniswap 'INSUFFICIENT_LIQUIDITY' on testnet - ethereum

I'm trying to get estimated eth needed to perform a swap on ropsten.
interface IUniswap {
function WETH() external pure returns (address);
function getAmountsOut(
uint amountIn,
address[] calldata path)
external
view
returns (uint[] memory amounts);
}
contract UniswapController {
address internal constant UNISWAP_ROUTER_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
IUniswap public uniswapRouter;
address private UNISWAP_DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
constructor() public {
uniswapRouter = IUniswap(UNISWAP_ROUTER_ADDRESS);
}
function getEstimatedETHforToken(uint daiAmount) public view returns (uint[] memory) {
return uniswapRouter.getAmountsOut(daiAmount, getPathForETHtoDAI());
}
function getWETH() public view returns(address) {
return uniswapRouter.WETH();
}
function getPathForETHtoDAI() public view returns (address[] memory) {
address[] memory path = new address[](2);
path[0] = uniswapRouter.WETH();
path[1] = UNISWAP_DAI_ADDRESS;
return path;
}
}
When I run getEstimatedETHforToken(amount) on remix ide, I get the error:
execution reverted: UniswapV2Library: INSUFFICIENT_LIQUIDITY
I suspect I have the wrong DAI stablecoin address, but this is the address on uniswap's site, which one should I use?

There doesn't seem to be good tokens use on testnets. Just forked the mainnet using ganache-cli and infura with this tutorial and it worked just fine.

Related

TypeError: "msg.value" and "callvalue()" can only be used in payable public functions

In my contract I'm trying to swap Eth for Dai using Uniswap's swapExactETHForTokens() function:
pragma solidity ^0.6.6;
interface IUniswap {
function swapExactETHForTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline)
external
payable
returns (uint[] memory amounts);
function WETH() external pure returns (address);
}
contract MyContract {
IUniswap uniswap;
constructor(address _uniswap) public {
uniswap = IUniswap(_uniswap);
}
function swapExactETHForTokens(uint amountOutMin, address token) external {
address[] memory path = new address[](2);
path[0] = uniswap.WETH();
path[1] = token;
uniswap.swapExactETHForTokens{value: msg.value}(
amountOutMin,
path,
msg.sender,
now
);
}
}
However on this line in swapExactETHForTokens():
uniswap.swapExactETHForTokens{value: msg.value}(
Remix IDE is showing the follow error:
contracts/MyContract.sol:26:42: TypeError: "msg.value" and "callvalue()" can only be used in payable public functions. Make the function "payable" or use an internal function to avoid this error.
uniswap.swapExactETHForTokens{value: msg.value}(
^-------^
I'm confused, because at the top I've already declared swapExactETHForTokens() to be payable in the IUniswap interface.
Search results for this error turned up blank so I thought it would be good to ask here. How can I fix this?
I realized my mistake: I needed to add the payable keyword to my own implementation of swapExactETHForTokens(), like so:
function swapExactETHForTokens(uint amountOutMin, address token) external payable { // payable keyword here
address[] memory path = new address[](2);
path[0] = uniswap.WETH();
path[1] = token;
uniswap.swapExactETHForTokens{value: msg.value}(
amountOutMin,
path,
msg.sender,
now
);
}

Solidity: calling function from deployed contract reverts

I'm trying to call the getNames() function on the reverse-record ens lookup contract here, but it's reverting. This is my code:
pragma solidity ^0.8.0; pragma experimental ABIEncoderV2;
contract ENStest {
/* ENS Reverse Lookup
Ropsten: 0x72c33B247e62d0f1927E8d325d0358b8f9971C68
Rinkeby: 0x196eC7109e127A353B709a20da25052617295F6f
Goerli: 0x333Fc8f550043f239a2CF79aEd5e9cF4A20Eb41e
Mainnet: 0x3671aE578E63FdF66ad4F3E12CC0c0d71Ac7510C
*/
address public ENSReverseLookupContractAddr = address(0x196eC7109e127A353B709a20da25052617295F6f); // Rinkeby
function addrToENS(address addr) public view returns(string[] memory) {
ReverseRecords ens = ReverseRecords(ENSReverseLookupContractAddr);
return ens.getNames([addr]);
}
}
// ENS Reverse Lookup Remote Contract
abstract contract ReverseRecords {
function getNames(address[] calldata addresses) external view virtual returns (string[] memory r);
}
Anyone know what I'm doing wrong here?
Resolved
I was casting a fixed-length array to a dynamic-sized array.
(h/t https://ethereum.stackexchange.com/a/103894/25695)
Revised code:
function addrToENS(address addr) public view returns(string[] memory) {
ReverseRecords ens = ReverseRecords(ENSReverseLookupContractAddr);
address[] memory t = new address[](1);
t[0] = addr;
return ens.getNames(t);
}

How to fix "Unidentified contract"? OpenSea is unable to “understand” ERC1155

I have deployed a ERC-1155 based contract (based on OpenZeppelin) and minted some NFTs on this contract successfully. But when I want to use these NFTs in OpenSea, it always says "Unidentified contract".
Example: https://testnets.opensea.io/assets/0xc7d3e4a5A0c3e14ba8C68ea1b8a99a9dBf3ca76F/2
API-Example: https://testnets-api.opensea.io/api/v1/asset/0xc7d3e4a5A0c3e14ba8C68ea1b8a99a9dBf3ca76F/2/?force_update=true
Following their official Tutorial repository (which does not compile any more because of outdated dependencies and other issues) I have added some (maybe) opensea-specific functions and data that might required for OpenSea in order to work properly. However, OpenSea is able to grab all required data to display an NFT, but as long as they say "Unidentified contract", this all makes no sense so far.
My question has:
has someone already managed to deploy a ERC-1155 and used it with OpenSea properly without this issue? Is there anything we have to "register" somehow contracts that are not based on ERC-721?
🔢 Code to reproduce
import "#openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "#openzeppelin/contracts/access/AccessControl.sol";
import "#openzeppelin/contracts/security/Pausable.sol";
import "#openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
contract OwnableDelegateProxy { }
contract ProxyRegistry {
mapping(address => OwnableDelegateProxy) public proxies;
}
contract MetaCoin is ERC1155, AccessControl, Pausable, ERC1155Burnable {
bytes32 public constant URI_SETTER_ROLE = keccak256("URI_SETTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
address proxyRegistryAddress;
constructor(address _proxyRegistryAddress) ERC1155("https://abcoathup.github.io/SampleERC1155/api/token/{id}.json") {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(URI_SETTER_ROLE, msg.sender);
_setupRole(PAUSER_ROLE, msg.sender);
_setupRole(MINTER_ROLE, msg.sender);
proxyRegistryAddress = _proxyRegistryAddress;
}
function setURI(string memory newuri) public onlyRole(URI_SETTER_ROLE) {
_setURI(newuri);
}
function pause() public onlyRole(PAUSER_ROLE) {
_pause();
}
function unpause() public onlyRole(PAUSER_ROLE) {
_unpause();
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC1155, AccessControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function mint(address account, uint256 id, uint256 amount, bytes memory data)
public
onlyRole(MINTER_ROLE)
{
_mint(account, id, amount, data);
}
function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
public
onlyRole(MINTER_ROLE)
{
_mintBatch(to, ids, amounts, data);
}
function _beforeTokenTransfer(address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
internal
whenNotPaused
override
{
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
}
/**
* Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-free listings.
*/
function isApprovedForAll(
address _owner,
address _operator
) public override view returns (bool isOperator) {
// Whitelist OpenSea proxy contract for easy trading.
ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
if (address(proxyRegistry.proxies(_owner)) == _operator) {
return true;
}
return ERC1155.isApprovedForAll(_owner, _operator);
}
}
💻 Environment
node: v16.7.0
deps:
"#openzeppelin/contracts": "^4.3.0",
"#nomiclabs/buidler": "^1.4.8",
"#nomiclabs/hardhat-ethers": "^2.0.2",
"#nomiclabs/hardhat-etherscan": "^2.1.1",
"#nomiclabs/hardhat-waffle": "^2.0.1",
"#openzeppelin/hardhat-upgrades": "^1.9.0",
"#typechain/ethers-v5": "^6.0.5",
"#typechain/hardhat": "^1.0.1",
"#types/chai": "^4.2.15",
"#types/chai-as-promised": "^7.1.3",
"#types/mocha": "^8.2.2",
"#types/node": "^14.14.37",
"chai": "^4.3.3",
"chai-as-promised": "^7.1.1",
"chai-datetime": "^1.8.0",
"ethereum-waffle": "^3.3.0",
"ethers": "^5.4.5",
"hardhat": "^2.6.1",
"hardhat-typechain": "^0.3.5",
"ts-generator": "^0.1.1",
"ts-node": "^9.1.1",
"typechain": "^4.0.3",
"typescript": "^4.2.4"
This is taken from name in your contract.
For ERC-1155 tokens, add a public variable name
string public name = "My Collection Name";
I finally found the root cause! OpenSea expects a public property called name in order to display the proper Name of the Collection instead of a static label Unidentified contract.
I came across this while looking at their reference code (which depends on a now 3-year-old MultiToken-Contract implementation and needs all in all some downgrades of Node and other tools in order to get it build [a downgrade to Node 10 worked best for me today] ).

Return value from a deployed smart contract, via a smart contract, to a smart contract

I am trying to return a value using a function of a deployed smart contract on the blockchain.
pragma solidity 0.6.2;
contract Caller {
address cont;
function changeAdd(address _change) public {
cont = _change;
}
function caller (bytes memory test) public returns(bool, bytes memory) {
bytes memory payload = abi.encodeWithSignature("callMe(bytes)", test);
(bool success, bytes memory result)= address(cont).call(payload);
return (success, (result));
}
function viewCont() public view returns(address) {
return cont;
}
}
And the deployed test contract is this:
pragma solidity 0.6.2;
contract Store {
uint counter;
function callMe(bytes calldata test) external returns(bytes memory) {
counter++;
return abi.encode(test);
}
function viewCounter () public view returns(uint256) {
return(counter);
}
function clearCounter() public {
counter = 0 ;
}
}
In this example, I am deploying contract "Store" on the blockchain where it is assigned a random address, which can be pointed at via the Caller.changeAdd function in order to use Caller.caller function. Thus, I am trying to send data in the form of bytes to the Store contract, which is supposed to send back the same data to the Caller contract. I am trying to isolate -only- the data that is originally sent, so I can use it to test interaction between smart contracts on the blockchain. I tried in the beginning to send an integer, but I couldn't find a way to do it. So I used bytes and it worked, but still the data I receive isn't the same that I send in the first place(e.g. I send 0x0 and I receive a big bytes number, which isn't the same as 0x0).
I could appreciate any help on how to receive and handle data between two different, unlinked smart contracts, thank you in advance.
Do you try to use abi.decode function of Solidity.
In the below example, contract B calls setName of contract A, then decodes the result by using abi.decode function.
contract A {
string public name;
constructor(string memory tokenName) public {
name = tokenName;
}
function setName(string memory newName) public returns ( string memory){
name = newName;
return newName;
}
}
contract B {
event Log(string msg);
string public myName;
function call(address addr, string memory newName) public {
bytes memory payload = abi.encodeWithSignature("setName(string)", newName);
(bool success, bytes memory result)= addr.call(payload);
// Decode data
string memory name = abi.decode(result, (string));
myName = name;
emit Log(name);
}
}

How to resolve this error in solidity "The constructor should be payable if you send value."?

In this solidity code the finalizeRequest() is giving a run-time error.
Here is the error :
Campaign.finalizeRequest(uint256) 0x692...77b3a
transact to Campaign.finalizeRequest errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The constructor should be payable if you send value. Debug the transaction to get more information.
Here is the code:
pragma solidity ^0.4.17;
contract Campaign {
struct Request {
string description;
uint value;
address recipient;
bool complete;
uint approvalCount;
mapping (address => bool) approvals;
}
address public manager;
uint public minimumContribution;
// address[] public approvers;
mapping (address => bool) public approvers;
Request[] public requests;
uint public approversCount;
function Campaign(uint minimum) public {
manager=msg.sender;
minimumContribution=minimum;
}
function contribute() public payable {
require(msg.value>minimumContribution);
// approvers.push(msg.sender);
approvers[msg.sender]=true;
approversCount++;
}
function createRequest(string description,uint value,address recipient) public restricted {
// require (approvers[msg.sender]);
Request memory newRequest=Request({description:description,value:value,recipient:recipient,complete:false,approvalCount:0});
requests.push(newRequest);
}
function approveRequest(uint index) public {
Request storage request=requests[index];
require(approvers[msg.sender]);
require(!request.approvals[msg.sender]);
request.approvals[msg.sender]=true;
request.approvalCount++;
}
function finalizeRequest(uint index) public restricted {
Request storage request = requests[index];
require(request.approvalCount>=(approversCount/2));
require(!request.complete);
request.recipient.transfer(request.value);
request.complete=true;
}
modifier restricted() {
require (msg.sender == manager);
_;
}
}
As far as I could debug, when I comment out request.recipient.transfer(request.value); in the finalizeRequest() function no runtime error is thrown. So error seems to be in this line of code.
As far as i see your finalizeRequest() function consists transfer of ether as defined request.recipient.transfer(request.value); so you need to make your finalizeRequest() as payable.
replace finalizeRequest() with:
function finalizeRequest(uint index) public restricted payable {
Request storage request = requests[index];
require(request.approvalCount>=(approversCount/2));
require(!request.complete);
request.recipient.transfer(request.value);
request.complete=true;
}
Thumb Rule: Whenever you are sending or receiving ether in any function, mark it as payable.
Reason why you need payable keyword is well explained here.