mirror of https://github.com/vacp2p/minime.git
Child -> Cloned
This commit is contained in:
parent
3471fed908
commit
3a9ef00cc5
|
@ -20,7 +20,7 @@ pragma solidity ^0.4.4;
|
||||||
/// @title MiniMeToken Contract
|
/// @title MiniMeToken Contract
|
||||||
/// @author Jordi Baylina
|
/// @author Jordi Baylina
|
||||||
/// @dev This token contract's goal is to make it easy to clone this token to
|
/// @dev This token contract's goal is to make it easy to clone this token to
|
||||||
/// spawn child tokens using the token distribution at a given block.
|
/// spawn cloned tokens using the token distribution at a given block.
|
||||||
/// @dev It is ERC20 compliant, but still needs to under go further testing.
|
/// @dev It is ERC20 compliant, but still needs to under go further testing.
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,7 +40,9 @@ contract Controlled {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contract TokenCreation {
|
// The controller should implement this interface if wants to receive the ether
|
||||||
|
// sent directly to the token contract.
|
||||||
|
contract Controller {
|
||||||
function proxyPayment(address _owner) payable returns(bool);
|
function proxyPayment(address _owner) payable returns(bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +55,7 @@ contract MiniMeToken is Controlled {
|
||||||
|
|
||||||
|
|
||||||
/// @dev `Checkpoint` is the structure that attaches a block number to the a
|
/// @dev `Checkpoint` is the structure that attaches a block number to the a
|
||||||
/// given token attribute
|
/// given value
|
||||||
struct Checkpoint {
|
struct Checkpoint {
|
||||||
|
|
||||||
// `fromBlock` is the block number that the value was generated from
|
// `fromBlock` is the block number that the value was generated from
|
||||||
|
@ -323,37 +325,37 @@ contract MiniMeToken is Controlled {
|
||||||
// Clone Token Method
|
// Clone Token Method
|
||||||
////////////////
|
////////////////
|
||||||
|
|
||||||
/// @notice Creates a new child token with the initial distribution being
|
/// @notice Creates a new cloned token with the initial distribution being
|
||||||
/// this token at `_snapshotBlock`
|
/// this token at `_snapshotBlock`
|
||||||
/// @param _childTokenName Name of the child token
|
/// @param _clonedTokenName Name of the cloned token
|
||||||
/// @param _childDecimalUnits Units of the child token
|
/// @param _clonedDecimalUnits Units of the cloned token
|
||||||
/// @param _childTokenSymbol Symbol of the child token
|
/// @param _clonedTokenSymbol Symbol of the cloned token
|
||||||
/// @param _snapshotBlock Block when the distribution of the parent token is
|
/// @param _snapshotBlock Block when the distribution of the parent token is
|
||||||
/// copied to set the initial distribution of the new child token;
|
/// copied to set the initial distribution of the new cloned token;
|
||||||
/// if the block is higher than the actual block, the current block is used
|
/// if the block is higher than the actual block, the current block is used
|
||||||
/// @param _isConstant True if transfers are not allowed in the child token
|
/// @param _isConstant True if transfers are not allowed in the cloned token
|
||||||
/// if the block is higher than the actual block, the current block is used
|
/// if the block is higher than the actual block, the current block is used
|
||||||
/// @return The address of the new MiniMeToken Contract
|
/// @return The address of the new MiniMeToken Contract
|
||||||
function createChildToken(
|
function createClonedToken(
|
||||||
string _childTokenName,
|
string _clonedTokenName,
|
||||||
uint8 _childDecimalUnits,
|
uint8 _clonedDecimalUnits,
|
||||||
string _childTokenSymbol,
|
string _clonedTokenSymbol,
|
||||||
uint _snapshotBlock,
|
uint _snapshotBlock,
|
||||||
bool _isConstant
|
bool _isConstant
|
||||||
) returns(address) {
|
) returns(address) {
|
||||||
if (_snapshotBlock > block.number) _snapshotBlock = block.number;
|
if (_snapshotBlock > block.number) _snapshotBlock = block.number;
|
||||||
MiniMeToken childToken = tokenFactory.createChildToken(
|
MiniMeToken clonedToken = tokenFactory.createClonedToken(
|
||||||
this,
|
this,
|
||||||
_snapshotBlock,
|
_snapshotBlock,
|
||||||
_childTokenName,
|
_clonedTokenName,
|
||||||
_childDecimalUnits,
|
_clonedDecimalUnits,
|
||||||
_childTokenSymbol,
|
_clonedTokenSymbol,
|
||||||
_isConstant
|
_isConstant
|
||||||
);
|
);
|
||||||
|
|
||||||
// An event to make the token easy to find on the blockchain
|
// An event to make the token easy to find on the blockchain
|
||||||
NewChildToken(address(childToken), _snapshotBlock);
|
NewClonedToken(address(clonedToken), _snapshotBlock);
|
||||||
return address(childToken);
|
return address(clonedToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
|
@ -446,7 +448,7 @@ contract MiniMeToken is Controlled {
|
||||||
/// contract) using the `proxyPayment` method.
|
/// contract) using the `proxyPayment` method.
|
||||||
function () payable {
|
function () payable {
|
||||||
if (controller == 0) throw;
|
if (controller == 0) throw;
|
||||||
if (! TokenCreation(controller).proxyPayment.value(msg.value)(msg.sender)) {
|
if (! Controller(controller).proxyPayment.value(msg.value)(msg.sender)) {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,7 +458,7 @@ contract MiniMeToken is Controlled {
|
||||||
// Events
|
// Events
|
||||||
////////////////
|
////////////////
|
||||||
event Transfer(address indexed _from, address indexed _to, uint256 _amount);
|
event Transfer(address indexed _from, address indexed _to, uint256 _amount);
|
||||||
event NewChildToken(address indexed _childToken, uint _snapshotBlock);
|
event NewClonedToken(address indexed _clonedToken, uint _snapshotBlock);
|
||||||
event Approval(
|
event Approval(
|
||||||
address indexed _owner,
|
address indexed _owner,
|
||||||
address indexed _spender,
|
address indexed _spender,
|
||||||
|
@ -470,11 +472,11 @@ contract MiniMeToken is Controlled {
|
||||||
// MiniMeTokenFactory
|
// MiniMeTokenFactory
|
||||||
////////////////
|
////////////////
|
||||||
|
|
||||||
// This contract is used to generate child contracts from a contract.
|
// This contract is used to generate cloned contracts from a contract.
|
||||||
// In solidity this is the way to create a contract from a contract of the same
|
// In solidity this is the way to create a contract from a contract of the same
|
||||||
// class
|
// class
|
||||||
contract MiniMeTokenFactory {
|
contract MiniMeTokenFactory {
|
||||||
function createChildToken(
|
function createClonedToken(
|
||||||
address _parentToken,
|
address _parentToken,
|
||||||
uint _snapshotBlock,
|
uint _snapshotBlock,
|
||||||
string _tokenName,
|
string _tokenName,
|
||||||
|
|
|
@ -21,7 +21,7 @@ var verbose = false;
|
||||||
// b[2] -> 0, 8, 2, 0
|
// b[2] -> 0, 8, 2, 0
|
||||||
// b[3] -> 0, 9, 1, 0
|
// b[3] -> 0, 9, 1, 0
|
||||||
// b[4] -> 0, 6, 1, 0
|
// b[4] -> 0, 6, 1, 0
|
||||||
// Child token
|
// Cloned token
|
||||||
// b[5] -> 0, 6, 1, 0
|
// b[5] -> 0, 6, 1, 0
|
||||||
// b[6] -> 0, 2, 5. 0
|
// b[6] -> 0, 2, 5. 0
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ var verbose = false;
|
||||||
|
|
||||||
describe('MiniMeToken test', function(){
|
describe('MiniMeToken test', function(){
|
||||||
var miniMeToken;
|
var miniMeToken;
|
||||||
var miniMeTokenChild;
|
var miniMeTokenCloned;
|
||||||
var b = [];
|
var b = [];
|
||||||
|
|
||||||
before(function(done) {
|
before(function(done) {
|
||||||
|
@ -310,12 +310,12 @@ describe('MiniMeToken test', function(){
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should Create the child token', function(done) {
|
it('Should Create the cloned token', function(done) {
|
||||||
this.timeout(200000000);
|
this.timeout(200000000);
|
||||||
async.series([
|
async.series([
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeToken.createChildToken(
|
miniMeToken.createClonedToken(
|
||||||
"Child Token 1",
|
"Cloned Token 1",
|
||||||
18,
|
18,
|
||||||
"MMTc",
|
"MMTc",
|
||||||
Number.MAX_SAFE_INTEGER,
|
Number.MAX_SAFE_INTEGER,
|
||||||
|
@ -327,10 +327,10 @@ describe('MiniMeToken test', function(){
|
||||||
function(err, txHash) {
|
function(err, txHash) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
ethConnector.web3.eth.getTransactionReceipt(txHash, function(err, res) {
|
ethConnector.web3.eth.getTransactionReceipt(txHash, function(err, res) {
|
||||||
var childTokenAddr = ethConnector.web3.toBigNumber(res.logs[0].topics[1]).toString(16);
|
var clonedTokenAddr = ethConnector.web3.toBigNumber(res.logs[0].topics[1]).toString(16);
|
||||||
while (childTokenAddr.length < 40) childTokenAddr = '0' + childTokenAddr;
|
while (clonedTokenAddr.length < 40) clonedTokenAddr = '0' + clonedTokenAddr;
|
||||||
childTokenAddr = '0x' + childTokenAddr;
|
clonedTokenAddr = '0x' + clonedTokenAddr;
|
||||||
miniMeTokenChild = ethConnector.web3.eth.contract( miniMeTokenHelper.miniMeTokenAbi).at(childTokenAddr);
|
miniMeTokenCloned = ethConnector.web3.eth.contract( miniMeTokenHelper.miniMeTokenAbi).at(clonedTokenAddr);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -344,42 +344,42 @@ describe('MiniMeToken test', function(){
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.parentToken(function(err, _parentAddress) {
|
miniMeTokenCloned.parentToken(function(err, _parentAddress) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(_parentAddress, miniMeToken.address);
|
assert.equal(_parentAddress, miniMeToken.address);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.parentSnapShotBlock(function(err, _parentSnapshotBlock) {
|
miniMeTokenCloned.parentSnapShotBlock(function(err, _parentSnapshotBlock) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(_parentSnapshotBlock, b[5]);
|
assert.equal(_parentSnapshotBlock, b[5]);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.totalSupply(function(err, _balance) {
|
miniMeTokenCloned.totalSupply(function(err, _balance) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_balance), 7);
|
assert.equal(ethConnector.web3.fromWei(_balance), 7);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.balanceOf(ethConnector.accounts[1], function(err, _balance) {
|
miniMeTokenCloned.balanceOf(ethConnector.accounts[1], function(err, _balance) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_balance), 6);
|
assert.equal(ethConnector.web3.fromWei(_balance), 6);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.totalSupplyAt(b[4], function(err, _balance) {
|
miniMeTokenCloned.totalSupplyAt(b[4], function(err, _balance) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_balance), 0);
|
assert.equal(ethConnector.web3.fromWei(_balance), 0);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.balanceOfAt(ethConnector.accounts[2], b[4], function(err, _balance) {
|
miniMeTokenCloned.balanceOfAt(ethConnector.accounts[2], b[4], function(err, _balance) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_balance), 0);
|
assert.equal(ethConnector.web3.fromWei(_balance), 0);
|
||||||
cb();
|
cb();
|
||||||
|
@ -389,10 +389,10 @@ describe('MiniMeToken test', function(){
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('Should move tokens in the child token from 2 to 3', function(done) {
|
it('Should move tokens in the cloned token from 2 to 3', function(done) {
|
||||||
async.series([
|
async.series([
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.transfer(ethConnector.accounts[2], ethConnector.web3.toWei(4), {
|
miniMeTokenCloned.transfer(ethConnector.accounts[2], ethConnector.web3.toWei(4), {
|
||||||
from: ethConnector.accounts[1],
|
from: ethConnector.accounts[1],
|
||||||
gas: 200000},
|
gas: 200000},
|
||||||
function(err) {
|
function(err) {
|
||||||
|
@ -410,14 +410,14 @@ describe('MiniMeToken test', function(){
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.balanceOf(ethConnector.accounts[1], function(err, _balance) {
|
miniMeTokenCloned.balanceOf(ethConnector.accounts[1], function(err, _balance) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_balance), 2);
|
assert.equal(ethConnector.web3.fromWei(_balance), 2);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.balanceOf(ethConnector.accounts[2], function(err, _balance) {
|
miniMeTokenCloned.balanceOf(ethConnector.accounts[2], function(err, _balance) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_balance), 5);
|
assert.equal(ethConnector.web3.fromWei(_balance), 5);
|
||||||
cb();
|
cb();
|
||||||
|
@ -438,49 +438,49 @@ describe('MiniMeToken test', function(){
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.balanceOfAt(ethConnector.accounts[1], b[5], function(err, _balance) {
|
miniMeTokenCloned.balanceOfAt(ethConnector.accounts[1], b[5], function(err, _balance) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_balance), 6);
|
assert.equal(ethConnector.web3.fromWei(_balance), 6);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.balanceOfAt(ethConnector.accounts[2], b[5], function(err, _balance) {
|
miniMeTokenCloned.balanceOfAt(ethConnector.accounts[2], b[5], function(err, _balance) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_balance), 1);
|
assert.equal(ethConnector.web3.fromWei(_balance), 1);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.balanceOfAt(ethConnector.accounts[1], b[4], function(err, _balance) {
|
miniMeTokenCloned.balanceOfAt(ethConnector.accounts[1], b[4], function(err, _balance) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_balance), 0);
|
assert.equal(ethConnector.web3.fromWei(_balance), 0);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.balanceOfAt(ethConnector.accounts[2], b[4], function(err, _balance) {
|
miniMeTokenCloned.balanceOfAt(ethConnector.accounts[2], b[4], function(err, _balance) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_balance), 0);
|
assert.equal(ethConnector.web3.fromWei(_balance), 0);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.totalSupply(function(err, _totalSupply) {
|
miniMeTokenCloned.totalSupply(function(err, _totalSupply) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_totalSupply), 7);
|
assert.equal(ethConnector.web3.fromWei(_totalSupply), 7);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.totalSupplyAt(b[5], function(err, _totalSupply) {
|
miniMeTokenCloned.totalSupplyAt(b[5], function(err, _totalSupply) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_totalSupply), 7);
|
assert.equal(ethConnector.web3.fromWei(_totalSupply), 7);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(cb) {
|
function(cb) {
|
||||||
miniMeTokenChild.totalSupplyAt(b[4], function(err, _totalSupply) {
|
miniMeTokenCloned.totalSupplyAt(b[4], function(err, _totalSupply) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(ethConnector.web3.fromWei(_totalSupply), 0);
|
assert.equal(ethConnector.web3.fromWei(_totalSupply), 0);
|
||||||
cb();
|
cb();
|
||||||
|
|
Loading…
Reference in New Issue