Our ICO is now live!
- LIVE: Telcoin ICO (Crowdsale Contract)
- LIVE: Telcoin (ERC20 Token Contract)
- Yarn
- Node.js 8.6.0 or newer
First, make sure you've installed development dependencies by running:
yarn
Next, start ganache-cli
:
make ganache
Finally, to run tests, simply execute:
make test
To deploy the TelcoinSale:
- Run
make bundle
to create./bundle/contracts/TelcoinSale.sol
. - In Parity's contract deployment view, load that file. Note that we're specifically avoiding
truffle deploy
to distance us from black magic as much as possible. - Deploy
Telcoin
first followed byTelcoinSale
. Provide the arguments listed below.
Argument | Value | Meaning |
---|---|---|
_distributor | 0x8322C7E7C14B57Ff85947F28381421692A1cF267 | Our multisig wallet allocates distribution pools. |
Argument | Value | Meaning |
---|---|---|
_softCap | 9000 ether | Contract successful if 9000 ether received. |
_hardCap | 22500 ether | Contract can finish early if 22500 ether received. |
_capFlex | 1500 | Flexibly increase caps by 150% (250% total). |
_startTime | 1513022400 | 2017-12-11T20:00:00.000Z |
_endTime | 1518379200 | 2018-02-11T20:00:00.000Z |
_rate | 1 | For every wei, give 1 sale/bonus token. |
_wallet | 0x8322C7E7C14B57Ff85947F28381421692A1cF267 | Our multisig wallet. |
_telcoin | 0x85e076361cc813A908Ff672F9BAd1541474402b2 | The address of the Telcoin ERC20 token contract. |
_bonusVestingStart | 1518465600 | 2018-02-12T20:00:00.000Z |
_bonusVestingDuration | 15552000 | 180 days. |
- A
Telcoin
contract is created with a fixed total supply of100,000,000,000.00
tokens, all of which are allocated to a multisig wallet for transfer to the various pools listed in the whitepaper. - A
TelcoinSale
contract is deployed with the arguments listed above. A non-zero value must be sent to the contract, which will then be sent to the wallet as a way to verify that the wallet is capable of actually receiving funds. - From the
Telcoin
contract,25,000,000,000.00
tokens are transferred to theTelcoinSale
. These tokens remain locked in the sale until it finishes. - It is not possible to participate in the sale until the sale starts.
- Before or after the sale starts, the contract owner must call
.whitelist(address, uint256, uint256, uint32)
to whitelist investors one by one, or multiple at once by calling.whitelistMany(address[], uint256, uint256, uint32)
. - Once the sale starts, whitelisted participants are able to either send Ether, or anyone can call
.buyTokens(address)
for a whitelisted address to purchase sale tokens.- Participants can also be allocated bonus tokens once their total contributions pass the whitelisted minimum amount. Bonus tokens will not be allocated earlier, but do apply retroactively once the minimum amount has been reached.
- Additionally, owners can call
.registerAltPurchase(address, symbol, transactionId, weiAmount)
for a whitelisted address to register a purchase in an alternate currency. A transaction ID or another method of verification is provided in thetransactionId
argument, so that at the very least the existence of a transaction can be verified. These registered purchases are not eligible for direct refunds from the smart contract.
- Our soft and hard cap are based on USD equivalent values. Should the USD/ETH exchange rate change considerably, we reserve the right to update the
capFlex
scale factor, which can either increase or decrease both the soft and hard cap. The effective caps have fixed minimum values and are calculated based on the formulacap + cap * (1000 / capFlex)
. - Sent Ether is locked in the
TelcoinSale
until.softCapReached()
, at which point due to it already being obvious that the sale will succeed and therefore no refunds will be issued, the contract owner will be able to.withdraw()
the balance accumulated so far. This reduces the risk of the contract getting hacked, and/or the full amount of funds getting permanently locked in the contract due to an error interacting with the wallet. - Before
endTime
is reached, it is possible to extend theTelcoinSale
by callingextendTime(uint256)
with a desired time extension, no greater than 7 days from the originalendTime
. - Once the
TelcoinSale
'sendTime
passes, the contract owner calls.finish()
on the contract. This finishes the minting of both sale and bonusTelcoinSaleToken
s, and depending on whethersoftCapReached()
, may either cause a final withdrawal, or allow refunds to be processed by setting therefunding
flag.- Alternatively, upon
.hardCapReached()
the sale can be finished early even ifendTime
has not been reached yet.
- Alternatively, upon
- If the goal was not reached, anyone will be able to call
.refund(address)
for any participant address, which will transfer the total amount deposited for the participant address to the participant address (importantly, not tomsg.sender
). The25,000,000,000.00
Telcoin are returned to the wallet.- Since we have no control over the wallet the investor used, there is a risk that an investor's wallet may have been rendered unusable by e.g. the Parity wallet suicide, or their fallback address may attempt to perform work that exceeds the gas stipend. For this reason, we implement an additional failsafe that allows all remaining funds to be withdrawn after 14 days have passed. Refunds can then be processed manually from the wallet, which requires trust, but is certainly better than potential loss of funds.
- If the goal was reached, both the sale token and bonus token contracts are transferred a portion of the
TelcoinSale
's25,000,000,000.00
Telcoin, proportionate to the combined amount of sale and bonus tokens.- The sale token provides a
.redeem(address)
method that upon being called calculates the portion of sale tokens the address holds and transfers a full equivalent portion of the Telcoin held by the sale token contract to the address. This method can be called by anyone. - The bonus token provides a
.redeem(address)
method that upon being called calculates the portion of bonus tokens the address holds and the amount that has vested so far, on a linear scale. An equivalent portion of theTelcoin
the bonus token contract holds is transferred to the address. This method can be called by anyone, and can be called multiple times during the vesting period. - Even after all participants have redeemed their Telcoin balances, a small amount of Telcoin may remain in the sale and bonus token contracts due to decimal rounding. This small number of tokens and/or token fractions is considered lost.
- The sale token provides a
The pre-sale has finished and is no longer available for new purchases.
To deploy the Presale:
- Run
make bundle
to create./bundle/contracts/PreSale.sol
. - In Parity's contract deployment view, load that file. Note that we're specifically avoiding
truffle deploy
to distance us from black magic as much as possible. - Deploy and provide the following arguments:
Argument | Value | Meaning |
---|---|---|
_goal | 1 ether | Contract successful if 1 ether received. |
_startTime | 1511899200 | 2017-11-28T20:00:00.000Z |
_endTime | 1512691200 | 2017-12-08T00:00:00.000Z |
_rate | 1 | For every wei, give 1 PreSale token. |
_wallet | 0x8322C7E7C14B57Ff85947F28381421692A1cF267 | Our multisig wallet. |
- A
PreSale
contract is deployed with the agreed upongoal
,startTime
,endTime
,rate
andwallet
arguments. These values were originally meant to be immutable, but following the Parity wallet suicide it was deemed necessary to have a method to change the wallet if needed. TheendTime
can also be extended by up to a maximum of 7 days as described below. A non-zero value must be sent to the contract, which will then be sent to the wallet as a way to verify that the wallet is capable of actually receiving funds. - It is not possible to participate in the sale until the sale starts.
- Before or after the sale starts, the contract owner must call
.whitelist(address, uint256, uint32)
to whitelist investors one by one. - Once the sale starts, whitelisted participants are able to either send ether, or anyone can call
.buyTokens(address)
for a whitelisted address to purchase pre-sale tokens. - Sent Ether is locked in the
PreSale
until.goalReached()
, at which point due to it already being obvious that the sale will succeed and therefore no refunds will be issued, the contract owner will be able to.withdraw()
the balance accumulated so far in order to reduce the risk of either the contract getting hacked or the full amount of funds getting permanently locked in the contract due to an error interacting with the wallet. - Before
endTime
is reached, it is possible to extend thePreSale
by callingextendTime(uint256)
with a desired time extension, no greater than 7 days from the originalendTime
. - Once the
PreSale
'sendTime
passes, the contract owner calls.finish()
on the contract. This finishes the minting ofPreSaleToken
, and depending on whethergoalReached()
or not, may either cause a final withdrawal, or allow refunds to be processed by setting therefunding
flag. - If the goal was not reached, anyone will be able to call
.refund(address)
for any participant address, which will transfer the total amount deposited for the participant address to the participant address (importantly, not tomsg.sender
).- Since we have no control over the wallet the investor used, there is a risk that an investor's wallet may have been rendered unusable by e.g. the Parity wallet suicide, or their fallback address may attempt to perform work that exceeds the gas stipend. For this reason, we implement an additional failsafe that allows all remaining funds to be withdrawn after 14 days have passed. Refunds can then be processed manually from the wallet, which requires trust, but is certainly better than potential loss of funds.
- If the goal was reached, the contract owner gains ownership of the
PreSaleToken
contract. - The token owner is able to
.allowExchanger(address)
to add a trusted "exchanger" contract to the token contract. - The exchanger has an e.g.
.redeem(address)
method, which calls.balanceOf(address)
on the pre-sale token, calculates the amount of final or intermediary tokens to grant for their balance, and calls.exchange(address, uint256, string, uint256)
to transfer the participant's pre-sale token balance to the exchanger's address. The exchanger should then grant the previously calculated amount of tokens to the participant. This requires a degree of trust from the participant, as the exchanger is able to make any decision based on the pre-sale token balance or any other factor.