Skip to content
This repository was archived by the owner on Jul 6, 2022. It is now read-only.

fixed airdrop alloc and added tests #44

Merged
merged 1 commit into from
Jan 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions contracts/PolyDistribution.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ contract PolyDistribution is Ownable {
uint256 amountClaimed; // Total tokens claimed
}
mapping (address => Allocation) public allocations;


// List of admins
mapping (address => bool) public airdropAdmins;


// Keeps track of whether or not a 250 POLY airdrop has been made to a particular address
mapping (address => bool) public airdrops;

modifier onlyOwnerOrAdmin() {
Expand Down Expand Up @@ -100,30 +102,27 @@ contract PolyDistribution is Ownable {
AVAILABLE_TOTAL_SUPPLY = AVAILABLE_TOTAL_SUPPLY.sub(_totalAllocated);
LogNewAllocation(_recipient, _supply, _totalAllocated, grandTotalAllocated());
}

/**
* @dev Add an airdrop admin
* @param _admin
* @param _isAdmin
*/
function setAirdropAdmin(address _admin, bool _isAdmin) public onlyOwner {
airdropAdmins[_admin] = _isAdmin;
}

/**
* @dev perform a transfer of allocations
* @param _reciepients
* @param _allocated
* @param _recipient is a list of recipients
*/
function airdropTokens(address[] _recipient) public onlyOwnerOrAdmin {
require(_startTime >= now);
require(now >= startTime);
uint airdropped;
for(uint8 i = 0; i< _recipient.length; i++)
{
if (!airdrops[_recipient[i]]) {
airdrops[_recipient[i]] = true;
require(POLY.transfer(_recipient[i], 250*(decimalsFactor));
airdropped = airdropped.add(250*decimalsFactor);
require(POLY.transfer(_recipient[i], 250 * decimalFactor));
airdropped = airdropped.add(250 * decimalFactor);
}
}
AVAILABLE_AIRDROP_SUPPLY = AVAILABLE_AIRDROP_SUPPLY.sub(airdropped);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"scripts": {
"test": "scripts/test.sh",
"compile": "truffle compile",
"coverage": "./node_modules/.bin/solidity-coverage",
"migrate-local": "truffle migrate --network=local --reset",
"migrate-ropsten": "truffle migrate --network=ropsten --reset",
"flatten": "sol-merger './contracts/*.sol' ./flat"
Expand Down
2 changes: 1 addition & 1 deletion scripts/csv_allocation.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async function setAllocation() {
if(prevAllocation[3].toNumber() ==0){
try{
console.log("Attempting to allocate",distribData[i][0], "to account",distribData[i][1]);
polyDistribution.setAllocation(distribData[i][1],new BigNumber(distribData[i][0] * (10 ** 18)),2,{from:accounts[0], gas:300000, gasPrice:5000000000});
polyDistribution.setAllocation(distribData[i][1],new BigNumber(distribData[i][0] * (10 ** 18)),2,{from:accounts[0], gas:300000, gasPrice:20000000000});
//let allocation = await polyDistribution.allocations(distribData[i][1],{from:accounts[0]});
//console.log(r);
//console.log("Allocated", allocation[3].toString(10), "tokens for account:",distribData[i][1]);
Expand Down
2 changes: 1 addition & 1 deletion scripts/distrib.csv
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,4 @@
5000,0x126910b84d1d270c1cf76aa1d3d9f3ab3932c7cd
1150,0x9a9e6588AF6d1bC42572B0E3c3D2F827dabA64Ac
4200,0x6d9ECe11860fDc4Ac3815eCF4077eae9973A7f2b
987,0x6d9ECe11860fDc4Ac3815eCF4077eae9973A7f2c
987,0xbf26b856d016421ce9187d3626b21ce6786af7f8
143 changes: 50 additions & 93 deletions test/TestPolyDistribution.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,25 @@ contract('PolyDistribution', function(accounts) {
let account_presale = accounts[1];
let account_founder1 = accounts[2];
let account_founder2 = accounts[3];
let account_airdrop1 = accounts[4];
let account_airdrop2 = accounts[5];
let account_bonus1 = accounts[6];
let account_advisor1 = accounts[7];
let account_advisor2 = accounts[8];
let account_reserve = accounts[9];

let account_admin1 = accounts[4];

let airdrop_massive = new Array();
for (var i = 0; i< 50; i++){
var acc = web3.eth.accounts.create();
airdrop_massive[i] = acc.address;
}

let airdrop_massive2 = new Array();
for (var i = 0; i< 50; i++){
var acc = web3.eth.accounts.create();
airdrop_massive2[i] = acc.address;
}

let allocationStruct = {
AllocationSupply: 0, // Type of allocation
endCliff: 0, // Tokens are locked until
Expand Down Expand Up @@ -122,10 +134,6 @@ contract('PolyDistribution', function(accounts) {
oldPresaleSupply = await polyDistribution.AVAILABLE_FOUNDER_SUPPLY({from:account_owner});
allocationTypeNum = 1;
break;
case "AIRDROP":
oldPresaleSupply = await polyDistribution.AVAILABLE_AIRDROP_SUPPLY({from:account_owner});
allocationTypeNum = 2;
break;
case "ADVISOR":
oldPresaleSupply = await polyDistribution.AVAILABLE_ADVISOR_SUPPLY({from:account_owner});
allocationTypeNum = 3;
Expand Down Expand Up @@ -169,9 +177,6 @@ contract('PolyDistribution', function(accounts) {
case "FOUNDER":
newPresaleSupply = await polyDistribution.AVAILABLE_FOUNDER_SUPPLY({from:account_owner});
break;
case "AIRDROP":
newPresaleSupply = await polyDistribution.AVAILABLE_AIRDROP_SUPPLY({from:account_owner});
break;
case "ADVISOR":
newPresaleSupply = await polyDistribution.AVAILABLE_ADVISOR_SUPPLY({from:account_owner});
break;
Expand Down Expand Up @@ -265,30 +270,6 @@ contract('PolyDistribution', function(accounts) {

});

describe("AIRDROP 1 Allocation", async function () {

let tokensToAllocate = 50;
doAllocationTests("AIRDROP",tokensToAllocate,account_airdrop1);

after(async() => {
oldTotalSupply = new BigNumber(oldTotalSupply.minus(tokensToAllocate));
grantTotalAllocationSum = new BigNumber(grantTotalAllocationSum.plus(tokensToAllocate));
});

});

describe("AIRDROP 2 Allocation", async function () {

let tokensToAllocate = 75;
doAllocationTests("AIRDROP",tokensToAllocate,account_airdrop2);

after(async() => {
oldTotalSupply = new BigNumber(oldTotalSupply.minus(tokensToAllocate));
grantTotalAllocationSum = new BigNumber(grantTotalAllocationSum.plus(tokensToAllocate));
});

});

describe("ADVISOR 1 Allocation", async function () {

let tokensToAllocate = 3333;
Expand Down Expand Up @@ -485,100 +466,76 @@ contract('PolyDistribution', function(accounts) {

});

});

describe("Withdraw 6 months after allocations", async function () {
it("should perform the AIRDROP for 50 accounts", async function () {
await polyDistribution.airdropTokens(airdrop_massive,{from:accounts[0]});

before(async() => {
//Time travel to startTime + 6 months;
await timeTravel((3600 * 24 * 180))// Move forward in time so the crowdsale has started
await mineBlock() // workaround for https://github.com/ethereumjs/testrpc/issues/336
});

it("should withdraw AIRDROP tokens", async function () {
let currentBlock = await web3.eth.getBlock("latest");

// Check token balance for account before calling transferTokens, then check afterwards.
let tokenBalance = await polyToken.balanceOf(account_airdrop1,{from:accounts[0]});
await polyDistribution.transferTokens(account_airdrop1,{from:accounts[0]});
let new_tokenBalance = await polyToken.balanceOf(account_airdrop1,{from:accounts[0]});
it("airdrop accounts should have 250 POLY each", async function () {
for (var i = 0; i< airdrop_massive.length; i++){
let tokenBalance = await polyToken.balanceOf(airdrop_massive[i],{from:accounts[0]});
assert.equal(tokenBalance.toString(10), "250000000000000000000");

//PRESALE tokens are completely distributed once allocated as they have no vesting period nor cliff
let allocation = await polyDistribution.allocations(account_airdrop1,{from:account_owner});
}
});

logWithdrawalData("AIRDROP",currentBlock.timestamp,account_airdrop1,contractStartTime,allocation,new_tokenBalance);
it("should set another admin for airdrop", async function () {
await polyDistribution.setAirdropAdmin(account_admin1,true,{from:accounts[0]});

let expectedTokenBalance = calculateExpectedTokens(allocation,currentBlock.timestamp,contractStartTime);
assert.equal(expectedTokenBalance.toString(10),new_tokenBalance.toString(10));
});

});
it("should perform the AIRDROP for 50 accounts with an admin", async function () {
await polyDistribution.airdropTokens(airdrop_massive2,{from:account_admin1});

});

describe("Withdraw 9 months after allocations", async function () {
it("airdrop accounts should have 250 POLY each", async function () {
for (var i = 0; i< airdrop_massive2.length; i++){
let tokenBalance = await polyToken.balanceOf(airdrop_massive2[i],{from:accounts[0]});
assert.equal(tokenBalance.toString(10), "250000000000000000000");

before(async() => {
//Time travel to startTime + 9 months;
await timeTravel((3600 * 24 * 90))// Move forward in time so the crowdsale has started
await mineBlock() // workaround for https://github.com/ethereumjs/testrpc/issues/336
}
});

it("should fail to withdraw AIRDROP 1 tokens as they have already been fully distributed", async function () {

try {
await polyDistribution.transferTokens(account_airdrop1,{from:accounts[0]});
} catch (error) {
let currentBlock = await web3.eth.getBlock("latest");

let new_tokenBalance = await polyToken.balanceOf(account_airdrop1,{from:accounts[0]});
let allocation = await polyDistribution.allocations(account_airdrop1,{from:account_owner});
logWithdrawalData("AIRDROP",currentBlock.timestamp,account_airdrop1,contractStartTime,allocation,new_tokenBalance);
});

logError("✅ Failed to withdraw");
return true;
}
throw new Error("I should never see this!")
describe("Withdraw 8 months after allocations", async function () {

before(async() => {
//Time travel to startTime + 8 months;
await timeTravel((3600 * 24 * 240))// Move forward in time so the crowdsale has started
await mineBlock() // workaround for https://github.com/ethereumjs/testrpc/issues/336
});

// it("should withdraw AIRDROP tokens", async function () {
// let currentBlock = await web3.eth.getBlock("latest");
//
// // Check token balance for account before calling transferTokens, then check afterwards.
// let tokenBalance = await polyToken.balanceOf(account_airdrop1,{from:accounts[0]});
// await polyDistribution.transferTokens(account_airdrop1,{from:accounts[0]});
// let new_tokenBalance = await polyToken.balanceOf(account_airdrop1,{from:accounts[0]});
//
// //PRESALE tokens are completely distributed once allocated as they have no vesting period nor cliff
// let allocation = await polyDistribution.allocations(account_airdrop1,{from:account_owner});
//
// logWithdrawalData("AIRDROP",currentBlock.timestamp,account_airdrop1,contractStartTime,allocation,new_tokenBalance);
//
// });

it("should withdraw AIRDROP tokens", async function () {
it("should withdraw RESERVE tokens", async function () {
let currentBlock = await web3.eth.getBlock("latest");

// Check token balance for account before calling transferTokens, then check afterwards.
let tokenBalance = await polyToken.balanceOf(account_airdrop2,{from:accounts[0]});
await polyDistribution.transferTokens(account_airdrop2,{from:accounts[0]});
let new_tokenBalance = await polyToken.balanceOf(account_airdrop2,{from:accounts[0]});
let tokenBalance = await polyToken.balanceOf(account_reserve,{from:accounts[0]});
await polyDistribution.transferTokens(account_reserve,{from:accounts[0]});
let new_tokenBalance = await polyToken.balanceOf(account_reserve,{from:accounts[0]});

//PRESALE tokens are completely distributed once allocated as they have no vesting period nor cliff
let allocation = await polyDistribution.allocations(account_airdrop2,{from:account_owner});
let allocation = await polyDistribution.allocations(account_reserve,{from:account_owner});

logWithdrawalData("AIRDROP",currentBlock.timestamp,account_airdrop2,contractStartTime,allocation,new_tokenBalance);
logWithdrawalData("RESERVE",currentBlock.timestamp,account_reserve,contractStartTime,allocation,new_tokenBalance);

let expectedTokenBalance = calculateExpectedTokens(allocation,currentBlock.timestamp,contractStartTime);
assert.equal(expectedTokenBalance.toString(10),new_tokenBalance.toString(10));
});


});



describe("Withdraw 15 months after allocations", async function () {

before(async() => {
//Time travel to startTime + 9 months;
await timeTravel((3600 * 24 * 180))// Move forward in time so the crowdsale has started
//Time travel to startTime + 15 months;
await timeTravel((3600 * 24 * 210))// Move forward in time so the crowdsale has started
await mineBlock() // workaround for https://github.com/ethereumjs/testrpc/issues/336
});

Expand Down
7 changes: 7 additions & 0 deletions truffle.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ module.exports = {
gas: 3500000,
gasPrice: 10000000000
},
ropsten: {
host: 'localhost',
port: 8545,
network_id: '3', // Match any network id
gas: 3500000,
gasPrice: 50000000000
},
local: {
host: 'localhost',
port: 8545,
Expand Down