Contract address - 0xfbf9ae92ecb05bc436d9b1e6c1d928824aedb2f1 - Self destructed
This contract allows participants to guess when they believe the price of ether (ETH) will next reach 500 USD. The contract is loaded with 0.5 ETH (though anyone can add more), and there are two possibilities to receive these funds.
- 10% of balance: The participant to first call
claimCheckPriceReward()once the oracle has setpriceConfirmedOver500to true. - 90% of balance: The participant whose timestamp guess is closest to when ETH hits the 500 USD mark according to the Kraken API.
So bottomline, if you want to participate, call makeGuess with your UNIX timestamp, and if you think your guess is strong relative to when we hit 500, call nominateSelfAsWinner with your address. If you want to win the 10% prize, keep an eye on this API call (specifically, the first value of the c array) as we approach 500 and call checkPrice followed by claimCheckPriceReward.
- When making a guess, participants include a UNIX timestamp.
msg.senderis the address that is making the guess and would receive the ETH.
- Guessing period is open for 14 days following contract creation.
- One guess per address, and participant can't change their guess once made. This is done to prevent people from changing their guess if price starts approaching 500USD during the 14 day guessing period.
- When
checkPriceis called, and assuming the price is greater than 500 USD based on Kraken's last trade between the ETHUSD pairing on their API, the oracle callback function setspriceConfirmedOver500to true andwinningTimestampis set to the current block timestamp.
- To call
checkPrice,msg.valueof the transaction must be >=oraclePrice(the return value oforaclize_getPrice("URL"), currently about .004 ETH). This is because the Oraclize callback requires a fee, which is taken out of the contract balance. First call is free. winningTimestampis determined by the blockchain and not the instant price breaks 500 on Kraken. Thus, all functions (exceptselfdestruct) can be called by anyone.- As an incentive mechanism to call
checkPriceas close as possible to when we actually pass 500USD, the first person to callclaimCheckPriceRewardAFTERpriceConfirmedOver500is set to true by the oracle is rewarded 10% of the contract's currenttotalAmount. To be clear, the person who gets the reward is not the person who calledcheckPricebut the person who calledclaimCheckPriceRewardafterpriceConfirmedOver500is set to true by the oracle. The reason for this is because there are possible gas errors by having the oracle__callbackcall other functions that change state.
- Now the nomination period begins and lasts for seven days. Instead of iterating over the myriad guesses that may exist, creating possible gas issues, people who think they have a chance of winning nominate themselves, creating a smaller subset of possible winners who effectively compete for the lowest difference between their guess and
winningTimestamp.
- The nomination period lasts for seven days following when
winningTimestampis established by the oracle.payoutcan be called by anyone following this seven day period, and the address who got closest towinningTimestamptakes all that remains intotalAmount. It doesn't matter if you guessed over or belowwinningTimestamp, it's all about who is closest. - Note, the contract does not account for the unlikely scenario where two or more addresses nominate themselves with the same
lowestDiffrelative towinningTimestamp(i.e., there will not be multiple winners or a tie). I experimented a little with a few ways of checking for/implementing this and just let it be. In this unique situation, the contract logic is such that the last address nominated during the nomination period would be set aswinner.
- Self Destruct - I have included an escape hatch that the
ownercan call in the event that there is some unforeseen logic error or if Kraken's API changes. The address hard-coded in the contract is for the nonprofit Give Directly (proof), who would receive the contract balance if this function is called.
- Remix with Metamask. Copy the contract into a new file, compile with Solidity 0.4.24, then go under the Run tab paste in the contract address where it says
at Address. This should allow you to interact with the various functions - MyEtherWallet: Copy the abi.json file in this repo and paste in the contract address
- Etherscan: Because the contract is verified, there is functionality in the block explorer that allow people to read and write to the contract using Metamask.
- There are other ways, to include Mist and the Geth command line. Submit a PR to include your preferred method!
- Rinkeby test
- Main net test
- There are many others self-destructed on Rinkeby
These contracts evolved during the testing period, and differed (in terms of the variables) only by setting the threshold lower for ETHUSD price (relative to current market price) and eliminating the amount of time to elapse to call certain functions.
This is an open source project. Contributions are welcomed & encouraged! 😄
- Allow for multiple winners
- Oracalize
- Kraken API
- UNIX Timestamp converter
- Compiled with Solidity 0.4.24