Skip to content

Commit

Permalink
Reword Sale -> Creation and Buy -> Create
Browse files Browse the repository at this point in the history
  • Loading branch information
LefterisJP committed Apr 18, 2016
1 parent 395d4e0 commit 5520181
Show file tree
Hide file tree
Showing 19 changed files with 119 additions and 107 deletions.
32 changes: 16 additions & 16 deletions DAO.sol
Expand Up @@ -21,14 +21,14 @@ Generic smart contract for a Decentralized Autonomous Organization (DAO)
to automate organizational governance and decision-making.
*/

import "./TokenSale.sol";
import "./TokenCreation.sol";
import "./ManagedAccount.sol";

contract DAOInterface {

// The amount of days for which people who try to participate in the sale
// by calling the fallback function will still get their ether back
uint constant saleGracePeriod = 40 days;
// The amount of days for which people who try to participate in the
// creation by calling the fallback function will still get their ether back
uint constant creationGracePeriod = 40 days;
// The minimum debate period that a generic proposal can have
uint constant minProposalDebatePeriod = 2 weeks;
// The minimum debate period that a split proposal can have
Expand Down Expand Up @@ -150,22 +150,22 @@ contract DAOInterface {

/// @dev Constructor setting the Curator and the address
/// for the contract able to create another DAO as well as the parameters
/// for the DAO Token Sale
/// for the DAO Token Creation
/// @param _curator The Curator
/// @param _daoCreator The contract able to (re)create this DAO
/// @param _proposalDeposit The deposit to be paid for a regular proposal
/// @param _minValue Minimal value for a successful DAO Token Sale
/// @param _closingTime Date (in Unix time) of the end of the DAO Token Sale
/// @param _privateSale If zero the DAO Token Sale is open to public, a
/// non-zero address means that the DAO Token Sale is only for the address
/// @param _minValue Minimal value for a successful DAO Token Creation
/// @param _closingTime Date (in Unix time) of the end of the DAO Token Creation
/// @param _privateCreation If zero the DAO Token Creation is open to public, a
/// non-zero address means that the DAO Token Creation is only for the address
// This is the constructor: it can not be overloaded so it is commented out
// function DAO(
// address _curator,
// DAO_Creator _daoCreator,
// uint _proposalDeposit,
// uint _minValue,
// uint _closingTime,
// address _privateSale
// address _privateCreation
// );

/// @notice Buy Token with `msg.sender` as the beneficiary
Expand Down Expand Up @@ -345,7 +345,7 @@ contract DAOInterface {
}

// The DAO contract itself
contract DAO is DAOInterface, Token, TokenSale {
contract DAO is DAOInterface, Token, TokenCreation {

// Modifier that allows only shareholders to vote and create new proposals
modifier onlyTokenholders {
Expand All @@ -359,8 +359,8 @@ contract DAO is DAOInterface, Token, TokenSale {
uint _proposalDeposit,
uint _minValue,
uint _closingTime,
address _privateSale
) TokenSale(_minValue, _closingTime, _privateSale) {
address _privateCreation
) TokenCreation(_minValue, _closingTime, _privateCreation) {

curator = _curator;
daoCreator = _daoCreator;
Expand All @@ -380,8 +380,8 @@ contract DAO is DAOInterface, Token, TokenSale {
}

function () returns (bool success) {
if (now < closingTime + saleGracePeriod)
return buyTokenProxy(msg.sender);
if (now < closingTime + creationGracePeriod)
return createTokenProxy(msg.sender);
else
return receiveEther();
}
Expand Down Expand Up @@ -636,7 +636,7 @@ contract DAO is DAOInterface, Token, TokenSale {
uint fundsToBeMoved =
(balances[msg.sender] * p.splitData[0].splitBalance) /
p.splitData[0].totalSupply;
if (p.splitData[0].newDAO.buyTokenProxy.value(fundsToBeMoved)(msg.sender) == false)
if (p.splitData[0].newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender) == false)
throw;


Expand Down
Expand Up @@ -17,24 +17,30 @@ along with the DAO. If not, see <http://www.gnu.org/licenses/>.


/*
By default, token purchases can be executed on behalf of another address using the TokenSale.sol buyTokenProxy() function
This contract is used as a fall back in case an exchange doesn't implement the "add data to a transaction" feature in a timely manner, preventing it from calling buyTokenProxy().
Calling this contract automatically triggers a call to buyTokenProxy() using the correct parameters for a given participant in the token sale.
A unique instance of such a contract would have to be deployed per participant, usually using a middleware layer on a webserver, for example.
* By default, token creation can be executed on behalf of another address using
* the TokenCreation.sol createTokenProxy() function This contract is used as a
* fall back in case an exchange doesn't implement the "add data to a
* transaction" feature in a timely manner, preventing it from calling
* createTokenProxy(). Calling this contract automatically triggers a call to
* createTokenProxy() using the correct parameters for a given participant in
* the token creation. A unique instance of such a contract would have to be
* deployed per participant, usually using a middleware layer on a webserver,
* for example.
*/

import "./TokenSale.sol";
import "./TokenCreation.sol";

contract DAOTokenSaleProxyTransferer {
contract DAOTokenCreationProxyTransferer {
address public owner;
address public dao;

//constructor
function DAOTokenSaleProxyTransferer(address _owner, address _dao) {
function DAOTokenCreationProxyTransferer(address _owner, address _dao) {
owner = _owner;
dao = _dao;

// just in case somebody already added values to this address, we will forward it right now.
// just in case somebody already added values to this address,
// we will forward it right now.
sendValues();
}

Expand All @@ -47,9 +53,9 @@ contract DAOTokenSaleProxyTransferer {
if (this.balance == 0)
return;

TokenSaleInterface funding = TokenSaleInterface(dao);
if (now > funding.closingTime() ||
!funding.buyTokenProxy.value(this.balance)(owner)) {
TokenCreationInterface fueling = TokenCreationInterface(dao);
if (now > fueling.closingTime() ||
!fueling.createTokenProxy.value(this.balance)(owner)) {

owner.send(this.balance);
}
Expand Down
8 changes: 4 additions & 4 deletions README.md
Expand Up @@ -49,17 +49,17 @@ Generic smart contract for a Decentralized Autonomous Organization (DAO) to auto
### Token.sol:
Defines the functions to check token balances, send tokens, send tokens on behalf of a 3rd party and its corresponding approval process.

### TokenSale.sol:
Token Sale contract, used by the DAO to sell its tokens and initialize its ether.
### TokenCreation.sol:
Token Creation contract, used by the DAO to sell its tokens and initialize its ether.

### SampleOffer.sol
Sample Proposal from a Contractor to the DAO. Feel free to use as a template for your own proposal.

### ManagedAccount.sol
Basic account, used by the DAO contract to separately manage both the rewards and the extraBalance accounts.

### DAOTokenSaleProxyTransferer.sol
This contract is used as a fall back in case an exchange doesn't implement the "add data to a transaction" feature in a timely manner, preventing it from calling buyTokenProxy().
### DAOTokenCreationProxyTransferer.sol
This contract is used as a fall back in case an exchange doesn't implement the "add data to a transaction" feature in a timely manner, preventing it from calling createTokenProxy().



Expand Down
2 changes: 1 addition & 1 deletion Token.sol
Expand Up @@ -20,7 +20,7 @@ along with the DAO. If not, see <http://www.gnu.org/licenses/>.
Basic, standardized Token contract with no "premine". Defines the functions to
check token balances, send tokens, send tokens on behalf of a 3rd party and the
corresponding approval process. Tokens need to be created by a derived
contract (e.g. TokenSale.sol).
contract (e.g. TokenCreation.sol).
Thank you ConsenSys, this contract originated from:
https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/Standard_Token.sol
Expand Down
62 changes: 33 additions & 29 deletions TokenSale.sol → TokenCreation.sol
Expand Up @@ -17,53 +17,57 @@ along with the DAO. If not, see <http://www.gnu.org/licenses/>.


/*
Token Sale contract, used by the DAO to sell its tokens and initialize its ether.
Feel free to modify the divisor method to implement different Token sale parameters
* Token Creation contract, used by the DAO to create its tokens and initialize
* its ether. Feel free to modify the divisor method to implement different
* Token Creation parameters
*/

import "./Token.sol";
import "./ManagedAccount.sol";

contract TokenSaleInterface {
contract TokenCreationInterface {

// End of token sale, in Unix time
// End of token creation, in Unix time
uint public closingTime;
// Minimum fueling goal of the token sale, denominated in ether
// Minimum fueling goal of the token creation, denominated in ether
uint public minValue;
// True if the DAO reached its minimum fueling goal, false otherwise
bool public isFueled;
// For DAO splits - if privateSale is 0, then it is a public sale, otherwise
// only the address stored in privateSale is allowed to purchase tokens
address public privateSale;
// hold extra ether which has been paid after the DAO token price has increased
// For DAO splits - if privateCreation is 0, then it is a public token
// creation, otherwise only the address stored in privateCreation is
// allowed to create tokens
address public privateCreation;
// hold extra ether which has been sent after the DAO token
// creation rate has increased
ManagedAccount public extraBalance;
// tracks the amount of wei given from each contributor (used for refund)
mapping (address => uint256) weiGiven;

/// @dev Constructor setting the minimum fueling goal and the
/// end of the Token Sale
/// @param _minValue Token Sale minimum fueling goal
/// @param _closingTime Date (in Unix time) of the end of the Token Sale
/// @param _privateSale Zero means that the sale is public. A non-zero
/// address represents the only address that can buy Tokens (the address
/// can also buy Tokens on behalf of other accounts)
/// end of the Token Creation
/// @param _minValue Token Creation minimum fueling goal
/// @param _closingTime Date (in Unix time) of the end of the Token Creation
/// @param _privateCreation Zero means that the creation is public. A
/// non-zero address represents the only address that can create Tokens
/// (the address can also create Tokens on behalf of other accounts)
// This is the constructor: it can not be overloaded so it is commented out
// function TokenSale(
// function TokenCreation(
// uint _minValue,
// uint _closingTime,
// address _privateSale
// address _privateCreation
// );

/// @notice Buy Token with `_tokenHolder` as the initial owner of the Token
/// @notice Create Token with `_tokenHolder` as the initial owner of the Token
/// @param _tokenHolder The address of the Tokens's recipient
/// @return Whether the purchase was successful
function buyTokenProxy(address _tokenHolder) returns (bool success);
function createTokenProxy(address _tokenHolder) returns (bool success);

/// @notice Refund `msg.sender` in the case the Token Sale didn't reach its
/// minimum fueling goal
/// @notice Refund `msg.sender` in the case the Token Creation did
/// not reach its minimum fueling goal
function refund();

/// @return The divisor used to calculate the token price during the sale
/// @return The divisor used to calculate the token creation rate during
/// the creation phase
function divisor() returns (uint divisor);

event FundingToDate(uint value);
Expand All @@ -72,17 +76,17 @@ contract TokenSaleInterface {
}


contract TokenSale is TokenSaleInterface, Token {
function TokenSale(uint _minValue, uint _closingTime, address _privateSale) {
contract TokenCreation is TokenCreationInterface, Token {
function TokenCreation(uint _minValue, uint _closingTime, address _privateCreation) {
closingTime = _closingTime;
minValue = _minValue;
privateSale = _privateSale;
privateCreation = _privateCreation;
extraBalance = new ManagedAccount(address(this), true);
}

function buyTokenProxy(address _tokenHolder) returns (bool success) {
function createTokenProxy(address _tokenHolder) returns (bool success) {
if (now < closingTime && msg.value > 0
&& (privateSale == 0 || privateSale == msg.sender)) {
&& (privateCreation == 0 || privateCreation == msg.sender)) {

uint token = (msg.value * 20) / divisor();
extraBalance.call.value(msg.value - token)();
Expand Down Expand Up @@ -120,10 +124,10 @@ contract TokenSale is TokenSaleInterface, Token {
// The fueling period starts with a 1:1 ratio
if (closingTime - 2 weeks > now) {
return 20;
// Followed by 10 days with a daily price increase of 5%
// Followed by 10 days with a daily creation rate increase of 5%
} else if (closingTime - 4 days > now) {
return (20 + (now - (closingTime - 2 weeks)) / (1 days));
// The last 4 days there is a constant price ratio of 1:1.5
// The last 4 days there is a constant creation rate ratio of 1:1.5
} else {
return 30;
}
Expand Down
10 changes: 5 additions & 5 deletions deploy/README.md
Expand Up @@ -12,20 +12,20 @@
At the moment of writting of this README the usage of the prepare script is:

```
usage: prepare.py [-h] [--solc SOLC] [--sale-duration-mins SALE_DURATION_MINS]
usage: prepare.py [-h] [--solc SOLC] [creation-duration-mins CREATION_DURATION_MINS]
DAO deployment script
optional arguments:
-h, --help show this help message and exit
--solc SOLC Full path to the solc binary to use
--sale-duration-mins SALE_DURATION_MINS
Deployed DAO sale duration in minutes
creation-duration-mins CREATION_DURATION_MINS
Deployed DAO Creation duration in minutes
```

You can for example call the script with a specifically compiled solc and set
the sale to end in 15 mins by doing:
the creation to end in 15 mins by doing:

```
./prepare.py --solc ~/ew/solidity/build/solc/solc --sale-duration-mins 15
./prepare.py --solc ~/ew/solidity/build/solc/solc creation-duration-mins 15
```
10 changes: 6 additions & 4 deletions deploy/prepare.py
Expand Up @@ -45,7 +45,9 @@ def compile_contract(self, contract_name):
def cleanup(self):
if self.args.no_limits:
rm_file(os.path.join(self.args.contracts_dir, "DAOcopy.sol"))
rm_file(os.path.join(self.args.contracts_dir, "TokenSaleCopy.sol"))
rm_file(
os.path.join(self.args.contracts_dir, "TokenCreationCopy.sol")
)


if __name__ == "__main__":
Expand All @@ -55,10 +57,10 @@ def cleanup(self):
help='Full path to the solc binary to use'
)
p.add_argument(
'--sale-duration-mins',
'--creation-duration-mins',
type=int,
default=60,
help='Deployed DAO sale duration in minutes'
help='Deployed DAO creation duration in minutes'
)
p.add_argument(
'--contracts-dir',
Expand Down Expand Up @@ -104,7 +106,7 @@ def cleanup(self):
comp['contracts']['DAO_Creator']['bin'])
)
f.write("seconds_from_now = {};\n".format(
args.sale_duration_mins * 60)
args.creation_duration_mins * 60)
)
f.write("curator = \"{}\";\n".format(args.curator))
f.write("default_proposal_deposit = {};\n".format(
Expand Down
2 changes: 1 addition & 1 deletion tests/README.md
Expand Up @@ -23,7 +23,7 @@ optional arguments:
console
--closing-time CLOSING_TIME
Number of minutes from now when the newly created DAO
sale ends
creation ends
--min-value MIN_VALUE
Minimum value to consider the DAO crowdfunded
--scenario {none,deploy,fund}
Expand Down
2 changes: 1 addition & 1 deletion tests/jsutils.py
Expand Up @@ -69,7 +69,7 @@ def js_common_intro(accounts_num):
if (dao_closing_time.gt(time_now())) {
testFail(
"Failed to create a proposal to: '" + desc + "' because the DAO's "
+ "sale time has not yet closed.\\ndao_closing_time: "
+ "creation time has not yet closed.\\ndao_closing_time: "
+ dao_closing_time + "\\nnow(): " + time_now()
);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/scenarios/deploy/arguments.json
@@ -1,7 +1,7 @@
[{
"name": "sale_seconds",
"name": "creation_seconds",
"default": 35,
"description":"Number of seconds from now when the newly created DAO sale ends",
"description":"Number of seconds from now when the newly created DAO creation ends",
"type":"int"
}, {
"name": "min_value",
Expand Down
2 changes: 1 addition & 1 deletion tests/scenarios/deploy/run.py
Expand Up @@ -10,7 +10,7 @@


def calculate_closing_time(obj, script_name, substitutions):
obj.closing_time = seconds_in_future(obj.args.deploy_sale_seconds)
obj.closing_time = seconds_in_future(obj.args.deploy_creation_seconds)
substitutions['closing_time'] = obj.closing_time
return substitutions

Expand Down

0 comments on commit 5520181

Please sign in to comment.