Skip to content

Instantly share code, notes, and snippets.

@retotrinkler
Created August 24, 2017 16:22
Show Gist options
  • Save retotrinkler/16ca09022c3924ea770eb26953165c22 to your computer and use it in GitHub Desktop.
Save retotrinkler/16ca09022c3924ea770eb26953165c22 to your computer and use it in GitHub Desktop.
Oyente Example
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract Fund {
/// Mapping of ether shares of the contract.
mapping(address => uint) shares;
/// Withdraw your share.
function withdraw() {
if (msg.sender.call.value(shares[msg.sender])())
shares[msg.sender] = 0;
}
}
contract ICO {
mapping(address => uint) magicBeans;
uint totalSupply;
address company;
uint constant fundingGoal = 100000 ether;
uint endOfFundingPeriod;
modifier checkInvariant() {
_;
if (this.balance != totalSupply) throw;
}
function ICO(uint _endOfFundingPeriod ) {
company = msg.sender;
endOfFundingPeriod = _endOfFundingPeriod;
}
function() {throw;}
function buyMagicBeans() payable checkInvariant() {
if (now > endOfFundingPeriod) throw;
magicBeans[msg.sender] += msg.value;
totalSupply += msg.value;
}
function refund() checkInvariant() returns(bool) {
uint tmpBeans = magicBeans[msg.sender];
magicBeans[msg.sender] = 0;
if (now > endOfFundingPeriod
&& totalSupply < fundingGoal
&& msg.sender.send(tmpBeans)) {
totalSupply -= tmpBeans;
return true;
}
else
magicBeans[msg.sender] = tmpBeans;
}
function fundTheProject() returns(bool) {
if (now > endOfFundingPeriod + 42 days
&& company.send(this.balance))
return true;
}
}
contract KingOfTheEtherThrone {
struct Monarch {
// Address to which their compensation will be sent.
address etherAddress;
// A name by which they wish to be known.
// NB: Unfortunately "string" seems to expose some bugs in web3.
string name;
// How much did they pay to become monarch?
uint claimPrice;
// When did their rule start (based on block.timestamp)?
uint coronationTimestamp;
}
// The wizard is the hidden power behind the throne; they
// occupy the throne during gaps in succession and collect fees.
address wizardAddress;
// Used to ensure only the wizard can do some things.
modifier onlywizard { if (msg.sender == wizardAddress) _; }
// How much must the first monarch pay?
uint constant startingClaimPrice = 100 finney;
// The next claimPrice is calculated from the previous claimFee
// by multiplying by claimFeeAdjustNum and dividing by claimFeeAdjustDen -
// for example, num=3 and den=2 would cause a 50% increase.
uint constant claimPriceAdjustNum = 3;
uint constant claimPriceAdjustDen = 2;
// How much of each claimFee goes to the wizard (expressed as a fraction)?
// e.g. num=1 and den=100 would deduct 1% for the wizard, leaving 99% as
// the compensation fee for the usurped monarch.
uint constant wizardCommissionFractionNum = 1;
uint constant wizardCommissionFractionDen = 100;
// How much must an agent pay now to become the monarch?
uint public currentClaimPrice;
// The King (or Queen) of the Ether.
Monarch public currentMonarch;
// Earliest-first list of previous throne holders.
Monarch[] public pastMonarchs;
// Create a new throne, with the creator as wizard and first ruler.
// Sets up some hopefully sensible defaults.
function KingOfTheEtherThrone() {
wizardAddress = msg.sender;
currentClaimPrice = startingClaimPrice;
currentMonarch = Monarch(
wizardAddress,
"[Vacant]",
0,
block.timestamp
);
}
function numberOfMonarchs() constant returns (uint n) {
return pastMonarchs.length;
}
// Fired when the throne is claimed.
// In theory can be used to help build a front-end.
event ThroneClaimed(
address usurperEtherAddress,
string usurperName,
uint newClaimPrice
);
// Fallback function - simple transactions trigger this.
// Assume the message data is their desired name.
function() {
claimThrone(string(msg.data));
}
// Claim the throne for the given name by paying the currentClaimFee.
function claimThrone(string name) {
uint valuePaid = msg.value;
// If they paid too little, reject claim and refund their money.
if (valuePaid < currentClaimPrice) {
msg.sender.send(valuePaid);
return;
}
// If they paid too much, continue with claim but refund the excess.
if (valuePaid > currentClaimPrice) {
uint excessPaid = valuePaid - currentClaimPrice;
msg.sender.send(excessPaid);
valuePaid = valuePaid - excessPaid;
}
// The claim price payment goes to the current monarch as compensation
// (with a commission held back for the wizard). We let the wizard's
// payments accumulate to avoid wasting gas sending small fees.
uint wizardCommission = (valuePaid * wizardCommissionFractionNum) / wizardCommissionFractionDen;
uint compensation = valuePaid - wizardCommission;
if (currentMonarch.etherAddress != wizardAddress) {
currentMonarch.etherAddress.send(compensation);
} else {
// When the throne is vacant, the fee accumulates for the wizard.
}
// Usurp the current monarch, replacing them with the new one.
pastMonarchs.push(currentMonarch);
currentMonarch = Monarch(
msg.sender,
name,
valuePaid,
block.timestamp
);
// Increase the claim fee for next time.
// Stop number of trailing decimals getting silly - we round it a bit.
uint rawNewClaimPrice = currentClaimPrice * claimPriceAdjustNum / claimPriceAdjustDen;
if (rawNewClaimPrice < 10 finney) {
currentClaimPrice = rawNewClaimPrice;
} else if (rawNewClaimPrice < 100 finney) {
currentClaimPrice = 100 szabo * (rawNewClaimPrice / 100 szabo);
} else if (rawNewClaimPrice < 1 ether) {
currentClaimPrice = 1 finney * (rawNewClaimPrice / 1 finney);
} else if (rawNewClaimPrice < 10 ether) {
currentClaimPrice = 10 finney * (rawNewClaimPrice / 10 finney);
} else if (rawNewClaimPrice < 100 ether) {
currentClaimPrice = 100 finney * (rawNewClaimPrice / 100 finney);
} else if (rawNewClaimPrice < 1000 ether) {
currentClaimPrice = 1 ether * (rawNewClaimPrice / 1 ether);
} else if (rawNewClaimPrice < 10000 ether) {
currentClaimPrice = 10 ether * (rawNewClaimPrice / 10 ether);
} else {
currentClaimPrice = rawNewClaimPrice;
}
// Hail the new monarch!
ThroneClaimed(currentMonarch.etherAddress, currentMonarch.name, currentClaimPrice);
}
// Used only by the wizard to collect his commission.
function sweepCommission(uint amount) onlywizard {
wizardAddress.send(amount);
}
// Used only by the wizard to collect his commission.
function transferOwnership(address newOwner) onlywizard {
wizardAddress = newOwner;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment