Skip to content

Instantly share code, notes, and snippets.

@alexvandesande
Last active October 21, 2021 04:40
Show Gist options
  • Save alexvandesande/859d3296ce62b70e2d49e43fe39ecbbe to your computer and use it in GitHub Desktop.
Save alexvandesande/859d3296ce62b70e2d49e43fe39ecbbe to your computer and use it in GitHub Desktop.
This is a first draft at what could be a continuous token sale. I just wrote it and haven't tested it but it shows the proof of concept: tokens are continuously generated in any curve desired and sold for the highest bidder. Since there's a maximum token sale speed, this guarantees that sales can't end too quickly. Since the sale always starts f…
pragma solidity ^0.4.2;
contract ethernalSale {
struct order {
uint amount;
address buyer;
}
mapping (uint => order) orderBook;
mapping (address => uint) balanceOf;
uint public highestPrice;
uint public totalSold;
uint public totalTokens;
uint public minAmount;
uint public saleStarted;
address public crowdseller;
// Generates an ethernal sale
function ethernalSale(){
minAmount = 1 ether / 1000;
saleStarted = now;
}
// adds a buy order. For simplicity's sake I have one order per price point.
// This shouldn't be a problem as you can have a min token deposit per price point
// and you can have very small price point differences
function putOrder(uint price) payable {
if (msg.value < minAmount) throw;
// there can be only one order per price point
// so it looks for a similar price point to add
bool seekPrice = true;
uint currPrice = price;
while(seekPrice) {
order o = orderBook[currPrice];
if (o.amount == 0 || currPrice < price - 100) seekPrice = false;
currPrice--;
}
// if still hasn't found, throw
if (o.amount != 0) throw;
// create a order
orderBook[currPrice] = order({amount: msg.value/currPrice, buyer: msg.sender});
if (currPrice > highestPrice) highestPrice = currPrice;
executeSale();
}
// cancels an order
function cancelOrder(uint price) {
order o = orderBook[price];
if (o.amount == 0 || o.buyer != msg.sender) throw;
uint valueToSend = price*o.amount;
orderBook[price] = order({amount: 0, buyer: 0});
msg.sender.transfer(valueToSend);
}
// a curve that generates how many tokens per seconds should be generated
function sellTargetByDate(uint targetTime) constant returns (uint sellTarget) {
// can be any curve: example targets 1 M tokens per day forever
return (1000000 * (targetTime - saleStarted)) / 1 days;
}
// anyone can call this, and it's also called at every put order
function executeSale() {
uint targetSale = sellTargetByDate(now) - totalSold;
uint currPrice = highestPrice;
while(targetSale > 0) {
// if it's about to run out of gas, stop it
if (msg.gas < 1000) targetSale = 0;
// loop throught the highest sale
order o = orderBook[currPrice];
if (o.amount <= targetSale) {
uint valueToSend = o.amount * currPrice;
targetSale -= o.amount;
totalSold += o.amount;
balanceOf[o.buyer] += o.amount;
orderBook[price] = order({amount: 0, buyer: 0});
crowdseller.transfer(valueToSend);
} else {
uint valueToSend = targetSale * currPrice;
totalSold += targetSale;
orderBook[price] = order({amount: o.amount - targetSale, buyer: o.buyer});
balanceOf[o.buyer] += targetSale;
targetSale = 0;
crowdseller.transfer(valueToSend);
}
currPrice--;
}
highestPrice = currPrice;
}
}
@pinnpe
Copy link

pinnpe commented Jun 2, 2017

Please help me write my token sale? ooh mighty one! :P

@5chdn
Copy link

5chdn commented Jun 2, 2017

@pinnpe
Copy link

pinnpe commented Jun 3, 2017

@5chdn thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment