Now I am using this dependency:"#chainlink/contracts": "^0.1.7" and solc v0.8
Facing this issue: Member "add" not found or not visible after argument-dependent lookup in struct Chainlink.Request memory
It's saying that Chainlink.Request doesn't have add function... please let me know how to fix it.
...
import "#chainlink/contracts/src/v0.8/dev/ChainlinkClient.sol";
contract ContractName is Ownable, ChainlinkClient {
constructor() {
setPublicChainlinkToken();
}
function requestData(
address _oracle,
bytes32 _jobId,
string memory _endpoint,
string memory _round,
string memory _seasonId
) public {
Chainlink.Request memory req =
buildChainlinkRequest(_jobId, address(this), this.fulfill.selector);
req.add(req, "endpoint", _endpoint);
req.add(req, "round", _round);
req.add(req, "season_id", _seasonId);
sendChainlinkRequestTo(_oracle, req, fee_);
}
enter image description here
Edit: Always be weary of contracts still in the dev branch. With that being said, v0.8 Chainlink Client is now out of the dev branch and this answer is still relevant.
I ran into the same issue and contacted Avneet from the Chainlink team. Turns out this is caused by a change in the Solidity language starting from v0.7:
Breaking change in v0.7:
using A for B only affects the contract it is mentioned in. Previously, the effect was inherited. Now, you have to repeat the using statement in all derived contracts that make use of the feature.
https://docs.soliditylang.org/en/v0.7.0/070-breaking-changes.html
Therefore, you need to add
using Chainlink for Chainlink.Request;
to the top of your contract, like so:
contract MyClient {
using Chainlink for Chainlink.Request;
Related
i had a small question that i creast a contract A and there is 1 busd token in the contract A, now i want to transfer the 1 busd out of contract by owner address
how to set the contractA?
i have use this code to deploy and test
pragma solidity ^0.8;
interface IERC20 {
function transfer(address to, uint256 amount) external returns (bool);
}
contract MyContract {
address owner = 0xFAD69bCefb704c1803A9Bf8f04BC314E78838F88;
function withdrawToken(address tokenContract, uint256 amount) external {
// send `amount` of tokens
// from the balance of this contract
// to the `owner` address
IERC20(tokenContract).transfer(owner, amount);
}
}
the feedback is
This contract may be abstract, it may not implement an abstract parent's methods completely or it may not invoke an inherited contract's constructor correctly.
can someone help me? thanks in advance , i am beginner.
find a way to transfer the busd out of contract .
I recognize this code from my other answer. :)
You're trying to deploy the IERC20 interface - which throws the "This contract may be abstract" error.
You need to deploy the other contract. Depending on how you deploy the contract, there are different ways to do that.
Here's another answer that shows how to select the desired contract in Remix IDE. However, note that this code won't work on the Remix emulated network, as the BUSD contract is not available there. You'll need to deploy the code either to the mainnet or your local fork of the mainnet, where the BUSD contract is available.
I'm trying to understand what this lines of BEP20 code mean, it is written in solidity
constructor () {
_rOwned[owner()] = _rTotal;
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E);
uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
.createPair(address(this), _uniswapV2Router.WETH());
uniswapV2Router = _uniswapV2Router;
_isExcludedFromFee[owner()] = true;
_isExcludedFromFee[address(this)] = true;
emit Transfer(address(0), owner(), _tTotal);
In the first lines, he instanciate UniswapV2Router pointing the address router to PancakeSwap. This because, he want to create a liquidity pool with his TOKEN and BNB, indeed after this instanciating operation he call createPair() that allows him to create this pair between his smart contract and the address WETH().
IMPORTANT: WETH() is a function that provider the chain native wrapped coin address where smart contract was deployed. For example: If I create a pair instanciating Uniswap router on Ethereum blockchain then WETH() will return address about WETH (Wrapping Ether) address present into Etheruem. On the contrary if I instanciate Uniswap Router with its address present into binance smart chain (and so I refers to Pancakeswap in this case), the value of WETH() will be WBNB address.
After this lines of code, I assume that he excluded from paying a fee for only transactions the owner() address (who deployed the smart contract for the first time) and smart contract itself.
Finally he emitted a Transfer event passing : address(0) (0x0000000000000000000000000000000000000000), owner() and total supply.
More information about pair on documentation.
Good afternoon,
I am new to Polygon (but have some Ethereum experience) and I am attempting to deploy the smart contract from the chainlink documentation https://docs.chain.link/docs/fulfilling-requests/ on the Polygon MUMBAI testnet, using remix as my in browser IDE.
I initially attempted to launch the original contract, as published in the docs. I got this error message:
"Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Internal JSON-RPC error. { "code": -32000, "message": "execution reverted" }"
When that failed, I trimmed it down to a smaller, more bare bones contract (in case there is a smart contract size limit on Polygon). Here is the trimmed down code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import "#chainlink/contracts/src/v0.8/ConfirmedOwner.sol";
contract ATestnetConsumer is ChainlinkClient, ConfirmedOwner {
using Chainlink for Chainlink.Request;
uint256 constant private ORACLE_PAYMENT = 1 * LINK_DIVISIBILITY/10;
uint256 public currentPrice;
int256 public changeDay;
bytes32 public lastMarket;
event RequestEthereumPriceFulfilled(
bytes32 indexed requestId,
uint256 indexed price
);
constructor() ConfirmedOwner(msg.sender){
setPublicChainlinkToken();
}
function requestEthereumPrice(address _oracle, string memory _jobId)
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), address(this), this.fulfillEthereumPrice.selector);
req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");
req.add("path", "USD");
req.addInt("times", 100);
sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
function fulfillEthereumPrice(bytes32 _requestId, uint256 _price)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestEthereumPriceFulfilled(_requestId, _price);
currentPrice = _price;
}
function getChainlinkToken() public view returns (address) {
return chainlinkTokenAddress();
}
function withdrawLink() public onlyOwner {
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer");
}
function cancelRequest(
bytes32 _requestId,
uint256 _payment,
bytes4 _callbackFunctionId,
uint256 _expiration
)
public
onlyOwner
{
cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration);
}
function stringToBytes32(string memory source) private pure returns (bytes32 result) {
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly { // solhint-disable-line no-inline-assembly
result := mload(add(source, 32))
}
}
}
But I get the same error. My wallet is funded with MATIC and LINK on polygon (mumbai). I am able to deploy the oracle contract to the mumbai testnet (and can see it on polygon scan https://mumbai.polygonscan.com/address/0x078cF10C20f7A8aac7b49F078B38007A49334b96 ), so it appears its all set up correctly, just for some reason this contract errors out.
I also increased the max gas I was willing to pay, I have attempted to just push the transaction through (it mines but the resulting contract fails to have any data https://mumbai.polygonscan.com/address/0xb9bc5681a15353c9b1b19d3db097323b92137ddd ).
I was also able to deploy a contract that does does not use Oracles but is a working contract (on Rinkeby) to Mumbai, further indicating its specific to this contract, or the Chainlink infrastructure on Polygon in general.
Side note, I am attempting to run and use my own Chainlink node on Polygon, but that should not be effecting this issue, as in this demo contract you send the node info and the job ID as parameters when you make a call to this function, its not in the smart contract itself.
What I have considered is wrong:
-Contract size is too big (even after I trimmed it down??)
-MATIC is not the only currency for gas on polygon?
-There is an unknown error in the Chinlink Documentation
-Something unique about Polygon is throwing an error
Thanks!
After going through and commenting line by line, I was able to track down the code that was at fault. I had gone in and changed the LINK address in ChainlinkClient.sol to the mumbai LINK address. As written, the demo code calls setPublicChainlinkToken(); which then assigns the stored value as the link token address. Changing that value to the correct address did not solve my issue. Instead, I used setChainlinkToken(0x326C977E6efc84E512bB9C30f76E30c160eD06FB); and that has cleared up my issue.
I have 2 Contracts. One is an ERC721 Token (NFTCollectables). The other one is a market including an auction system (NFTMarket).
An auction can be claimed after it ended and only by the highest bidder.
When claiming an auction the transfer method of the NFTCollectables contract is called to transfer the NFT from the markets address to the address of the highest bidder.
I do not exactly understand why the exception comes, but it occurs at/inside the transfer method of the NFTCollectables contract. The strange thing is that even the last line of code inside the transfer method is getting executed (tested by putting a require(false, 'test') after _transfer(msg.sender, to, nftId)). But nothing after ctr.transfer(auction.highestBid.bidder, auction.nftId) is getting executed (tested by putting a require(false, 'test') after it).
Could it have to do with the gas limit?
Any idea is appreciated, thanks!
NFTMarket
function claimAuction(uint auctionIndex) external {
require(auctionIndex < auctions.length, "no auction");
Auction memory auction = auctions[auctionIndex];
require(block.timestamp <= auction.end, "auction still active");
NFTCollectables ctr = NFTCollectables(nftCollectablesAddress);
ctr.transfer(auction.highestBid.bidder, auction.nftId);
// deleting auction from active auctions list
for (uint i; i < activeAuctionIndexes.length; i++) {
if (activeAuctionIndexes[i] == auctionIndex) {
delete activeAuctionIndexes[i];
break;
}
}
emit AuctionEnd(auction.highestBid.bidder, auction.highestBid.price, auction.nftId);
}
NFTCollectables
function transfer(address payable to, uint nftId) external payable {
require(_exists(nftId), "transfer of non existing token");
require(_isApprovedOrOwner(msg.sender, nftId), "Sender not approved nor owner");
_transfer(msg.sender, to, nftId);
}
If you have deployed the contracts on the public network, like mainnet or testnet, use https://tenderly.co or EtherScan to debug the revert reason.
If you are running the contracts using unit tests then keep modifying the contracts e.g. by removing lines to see when it starts failing. Or alternatively use a better smart contract development framework like Brownie which will give you the cause of revert right away.
We had implemented a function on our codebase that i can share with you. This function is used to transfer ownership of nft to who wins the auction.
function transferNFTtoNewOwner(NFTItem memory t,address oldOwner, address newOwner) internal {
require(newOwner != address(0), "New owner can't be address zero.");
XXXX storage r = creatureList[t.tokenAddress][t.tokenId];
IERC721 nft = IERC721(t.tokenAddress);
nft.safeTransferFrom(oldOwner, newOwner, t.tokenId);
address currOwner = nft.ownerOf(t.tokenId);
require(newOwner == currOwner, "Problem on nft transfer");
r.owner = newOwner;
}
The major differences are we used safetransferfrom here. If your contract owns the NFT then you can call safeTransfer. and after that we checked the nft owner with require statement. If you put this statement and change your transfer function to safetransfer and the transaction still revert without giving any error on etherscan then you can investigate about your nft contract.
I am practicing some vulnerabilities in smart contracts for my lecture in the university.
The contracts that I am practicing on are;
contract Company is CompanyInterface {
address public ceo;
...
function setCeo(address newCeo){
ceo = newCeo;
}
...
}
contract MainCompany is CompanyInterface {
address public ceo;
address public lib; // address of Company contract
...
function() payable external {
if(!lib.delegatecall(msg.data)) {
revert();
}
}
...
}
Here, I try to make myself ceo of the MainCompany. However, I couldn't figure out how to call setCeo here. As I know that when an attacker calls MainCompany.setCeo(attacker), MainCompany's fallback function should be triggered when the function (setCeo) can't be found in the MainCompany contract. However, it doesn't happen.
My approach is to create an attacker contract. In that contract, I created a function that does the following;
<addressOfMainCompany>.call.value(1)(bytes4(keccak256("setCeo(address)")), address(0x4b9...));
But ceo is still same. What is the correct way of changing ceo of the MainCompany here?
Thanks