Exemple #1
0
        public static object HandleHelperOperation(string operation, params object[] args)
        {
            switch (operation)
            {
            case "BalanceOfVestedAddress":
                // retrieve the real balance of an address that has been subjected to whitepaper defined vesting period
                if (!Helpers.RequireArgumentLength(args, 1))
                {
                    return(false);
                }
                return(Helpers.BalanceOfVestedAddress((byte[])args[0]));

            case "IsPrivateSaleAllocationLocked":
                // if the admin method `Administration.AllocatePresalePurchase` is permanently disabled, this method will return
                // the timestamp the lock was put in place.
                return(Storage.Get(Storage.CurrentContext, StorageKeys.PrivateSaleAllocationLocked()));

            case "supportedStandards":
                // support NEP-10 by responding to supportedStandards
                // https://github.com/neo-project/proposals/blob/master/nep-10.mediawiki
                return(ICOTemplate.SupportedStandards());

            case "BalanceOfSaleContribution":
                if (!Helpers.RequireArgumentLength(args, 1))
                {
                    return(false);
                }
                return(Helpers.BalanceOfSaleContribution((byte[])args[0]));
            }
            return(false);
        }
        /// <summary>
        /// Claims unsold tokens
        /// </summary>
        /// <returns></returns>
        public static bool ClaimUnsoldTokens()
        {
            bool UnsoldTokensClaimed = Storage.Get(Storage.CurrentContext, StorageKeys.UnsoldTokensClaimed()).AsString() == "1";

            //This method can only be executed by the admin account, after the public sale, and can only be called once (use UnsoldTokensClaimed() storage item)
            if (Helpers.GetBlockTimestamp() >= ICOTemplate.PublicSaleEndTime() && UnsoldTokensClaimed == false && Helpers.VerifyIsAdminAccount())
            {
                byte[] address = ICOTemplate.AdditionalCompanyTokenFund;

                //Get amount remaining
                BigInteger amountRemaining = NEP5.CrowdsaleAvailableAmount();

                //Add vested amount to account
                TokenSale.SetVestingPeriodForAddress(address, "company", amountRemaining);

                //Set total supply
                Helpers.SetTotalSupply(amountRemaining);

                //Set the UnsoldTokensClaimed() storage item so ClaimUnsoldTokens() cannot be called again
                Storage.Put(Storage.CurrentContext, StorageKeys.UnsoldTokensClaimed(), "1");

                transfer(null, address, amountRemaining);

                Runtime.Notify("ClaimUnsoldTokens() tokens allocated", address, amountRemaining);

                return(true);
            }

            return(false);
        }
Exemple #3
0
        /// <summary>
        /// allow allocation of presale purchases by contract administrator. this allows the moonlight team to allocate the 25% of LX tokens sold in the private presale.
        /// as we accepted ETH in addition to NEO&GAS, using a mintTokens method here is not practical.
        /// 1. this method will not allow the presale allocation to exceed the defined amount
        /// 2. this method is permanently disabled once the method `LockPresaleAllocation` has been called.
        /// 3. the state of the `LockPresaleAllocation` can be determined by the public using the method `IsPresaleAllocationLocked` (returns timestamp that lock was put in place)
        /// </summary>
        /// <param name="address"></param>
        /// <param name="amountPurchased"></param>
        /// <returns></returns>
        public static bool AllocatePresalePurchase(byte[] address, BigInteger amountPurchased)
        {
            bool presaleLocked = Storage.Get(Storage.CurrentContext, StorageKeys.PresaleAllocationLocked()).AsBigInteger() > 0;

            if (presaleLocked)
            {
                Runtime.Notify("AllocatePresalePurchase() presaleLocked, can't allocate");
                return(false);
            }

            BigInteger presaleAllocationMaxValue = ((ICOContract.TokenMaxSupply * (BigInteger)ICOContract.PresaleAllocationPercentage()) / 100) * NEP5.factor;
            BigInteger presaleAllocatedValue     = Storage.Get(Storage.CurrentContext, StorageKeys.PresaleAllocatedValue()).AsBigInteger();

            if ((presaleAllocatedValue + amountPurchased) > presaleAllocationMaxValue)
            {
                // this purchase will exceed the presale cap.. dont allow
                Runtime.Notify("AllocatePresalePurchase() purchase will exceed presale max allocation");
                return(false);
            }

            TokenSale.SetVestingPeriodForAddress(address, amountPurchased);
            Storage.Put(Storage.CurrentContext, StorageKeys.PresaleAllocatedValue(), presaleAllocatedValue + amountPurchased);
            Runtime.Notify("AllocatePresalePurchase() tokens allocated", address, amountPurchased);

            return(true);
        }
Exemple #4
0
        /// <summary>
        /// determine if TransferFrom whitelisting is enabled for this contract or not
        /// </summary>
        /// <returns></returns>
        public static bool IsTransferFromWhitelistingEnabled()
        {
            bool isEnabled = Storage.Get(Storage.CurrentContext, StorageKeys.WhiteListTransferFromSettingChecked()).AsString() == "1";

            Runtime.Notify("IsTransferFromWhitelistingEnabled isEnabled", isEnabled);
            return(isEnabled);
        }
Exemple #5
0
        /// <summary>
        /// a new token is minted, set the total supply value
        /// </summary>
        /// <param name="newlyMintedTokens">the number of tokens to add to the total supply</param>
        public static void SetTotalSupply(BigInteger newlyMintedTokens)
        {
            BigInteger currentTotalSupply = NEP5.TotalSupply();

            Runtime.Notify("SetTotalSupply() setting new totalSupply", newlyMintedTokens + currentTotalSupply);

            Storage.Put(Storage.CurrentContext, StorageKeys.TokenTotalSupply(), currentTotalSupply + newlyMintedTokens);
        }
        /// <summary>
        /// mint tokens is called when a user wishes to purchase tokens
        /// </summary>
        /// <returns></returns>
        public static bool MintTokens()
        {
            object[]    transactionData = Helpers.GetTransactionAndSaleData();
            Transaction tx = (Transaction)transactionData[0];

            byte[]     sender                    = (byte[])transactionData[1];
            byte[]     receiver                  = (byte[])transactionData[2];
            ulong      receivedNEO               = (ulong)transactionData[3];
            ulong      receivedGAS               = (ulong)transactionData[4];
            BigInteger whiteListGroupNumber      = (BigInteger)transactionData[5];
            BigInteger crowdsaleAvailableAmount  = (BigInteger)transactionData[6];
            BigInteger groupMaximumContribution  = (BigInteger)transactionData[7];
            BigInteger totalTokensPurchased      = (BigInteger)transactionData[8];
            BigInteger neoRemainingAfterPurchase = (BigInteger)transactionData[9];
            BigInteger gasRemainingAfterPurchase = (BigInteger)transactionData[10];
            BigInteger totalContributionBalance  = (BigInteger)transactionData[11];

            if (Helpers.GetBlockTimestamp() >= ICOTemplate.PublicSaleEndTime())
            {
                Runtime.Notify("MintTokens() failed. Token Sale is closed.", false);
                return(false);
            }

            if (!CanUserParticipateInSale(transactionData))
            {
                Runtime.Notify("MintTokens() CanUserParticipate failed", false);
                return(false);
            }

            byte[] lastTransactionHash = Storage.Get(Storage.CurrentContext, StorageKeys.MintTokensLastTX());
            if (lastTransactionHash == tx.Hash)
            {
                // ensure that minTokens doesnt process the same transaction more than once
                Runtime.Notify("MintTokens() not processing duplicate tx.Hash", tx.Hash);
                return(false);
            }

            Storage.Put(Storage.CurrentContext, StorageKeys.MintTokensLastTX(), tx.Hash);
            Runtime.Notify("MintTokens() receivedNEO / receivedGAS", receivedNEO, receivedGAS);

            if (neoRemainingAfterPurchase > 0 || gasRemainingAfterPurchase > 0)
            {
                // this purchase would have exceed the allowed max supply so we spent what we could and will refund the remainder
                refund(sender, neoRemainingAfterPurchase, gasRemainingAfterPurchase);
            }

            BigInteger senderAmountSubjectToVesting = SubjectToVestingPeriod(sender);
            BigInteger newTokenBalance = NEP5.BalanceOf(sender) + totalTokensPurchased + senderAmountSubjectToVesting;

            Helpers.SetBalanceOf(sender, newTokenBalance);
            Helpers.SetBalanceOfSaleContribution(sender, totalContributionBalance);
            Helpers.SetTotalSupply(totalTokensPurchased);

            transfer(null, sender, totalTokensPurchased);
            return(true);
        }
        /// <summary>
        /// allow the contract administrator to update the admin address
        /// </summary>
        /// <param name="newAdminAddress"></param>
        /// <returns></returns>
        public static bool UpdateAdminAddress(byte[] newAdminAddress)
        {
            if (newAdminAddress.Length != 20)
            {
                return(false);
            }

            Storage.Put(Storage.CurrentContext, StorageKeys.ContractAdmin(), newAdminAddress);
            return(true);
        }
Exemple #8
0
        /// <summary>
        /// allow an administrator to request the unlocking of founder tokens
        /// </summary>
        /// <param name="address">founders script hash</param>
        /// <param name="roundNumber">1-7</param>
        /// <returns></returns>
        public static bool UnlockFoundersTokens(byte[] address, int roundNumber)
        {
            if (address.Length != 20)
            {
                Runtime.Log("UnlockFoundersTokens() invalid address supplied");
                return(false);
            }

            byte[]     roundKey       = address.Concat(((BigInteger)roundNumber).AsByteArray());
            StorageMap unlockedRounds = Storage.CurrentContext.CreateMap(StorageKeys.FounderTokenUnlockRound());

            bool roundPreviouslyUnlocked = unlockedRounds.Get(roundKey).AsBigInteger() > 0;

            if (roundPreviouslyUnlocked)
            {
                Runtime.Log("UnlockFoundersTokens() round already unlocked");
                return(false);
            }

            object[] foundersVestingPeriod = GetCoreTeamVestingSchedule();

            uint currentTimestamp = Helpers.GetBlockTimestamp();
            int  roundIndex       = (roundNumber * 2) - 2;
            int  roundValueIndex  = roundIndex + 1;

            if (roundIndex < 0)
            {
                Runtime.Log("UnlockFoundersTokens() invalid round index (<0)");
                return(false);
            }

            uint       roundReleaseDate   = (uint)foundersVestingPeriod[roundIndex];
            BigInteger roundReleaseAmount = (BigInteger)foundersVestingPeriod[roundValueIndex];

            if (currentTimestamp < roundReleaseDate)
            {
                Runtime.Log("UnlockFoundersTokens() not scheduled for release");
                return(false);
            }


            object[] founderKeys = ICOContract.MoonlightFounderKeys();
            for (int i = 0; i < founderKeys.Length; i++)
            {
                byte[] founderKey = (byte[])founderKeys[i];
                if (founderKey == address)
                {
                    Runtime.Notify("UnlockFoundersTokens() releasing funds. currentTimestamp / roundReleaseDate / roundReleaseAmount", currentTimestamp, roundReleaseDate, roundReleaseAmount);
                    Helpers.SetBalanceOf(founderKey, NEP5.BalanceOf(founderKey) + roundReleaseAmount);            // set new balance for destination account
                    unlockedRounds.Put(roundKey, "1");
                    return(true);
                }
            }
            return(false);
        }
Exemple #9
0
        /// <summary>
        /// retrieve the group number the whitelisted address is in
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public static BigInteger GetWhitelistGroupNumber(byte[] address)
        {
            if (address.Length != 20)
            {
                return(0);
            }

            StorageMap kycWhitelist = Storage.CurrentContext.CreateMap(StorageKeys.KYCWhitelistPrefix());

            return(kycWhitelist.Get(address).AsBigInteger());
        }
Exemple #10
0
 /// <summary>
 /// verify the contract invoker is the defined administrator
 /// </summary>
 /// <returns></returns>
 public static bool VerifyIsAdminAccount()
 {
     if (ContractInitialised())
     {
         return(VerifyWitness(Storage.Get(Storage.CurrentContext, StorageKeys.ContractAdmin())));
     }
     else
     {
         return(VerifyWitness(ICOTemplate.InitialAdminAccount));
     }
 }
Exemple #11
0
        /// <summary>
        /// helper method to retrieve the stored group unlock block height
        /// </summary>
        /// <param name="groupNumber"></param>
        /// <returns></returns>
        public static uint GetGroupUnlockBlock(BigInteger groupNumber)
        {
            if (groupNumber <= 0)
            {
                return(0);
            }

            StorageMap unlockBlock = Storage.CurrentContext.CreateMap(StorageKeys.GroupUnlockPrefix());

            return((uint)unlockBlock.Get(groupNumber.AsByteArray()).AsBigInteger());
        }
Exemple #12
0
        /// <summary>
        /// get the maximum number of LX that can be purchased by groupNumber during the public sale
        /// </summary>
        /// <param name="groupNumber"></param>
        /// <returns></returns>
        public static BigInteger GetGroupMaxContribution(BigInteger groupNumber)
        {
            StorageMap contributionLimits = Storage.CurrentContext.CreateMap(StorageKeys.GroupContributionAmountPrefix());
            BigInteger maxContribution    = contributionLimits.Get(groupNumber.AsByteArray()).AsBigInteger();

            if (maxContribution > 0)
            {
                return(maxContribution);
            }

            return(ICOContract.MaximumContributionAmount());
        }
Exemple #13
0
        public static BigInteger Allowance(byte[] from, byte[] to)
        {
            if (from.Length != 20 || to.Length != 20)
            {
                Runtime.Log("Allowance() invalid from|to address supplied");
                return(0);
            }

            StorageMap allowances = Storage.CurrentContext.CreateMap(StorageKeys.TransferAllowancePrefix());

            return(allowances.Get(from.Concat(to)).AsBigInteger());
        }
Exemple #14
0
        /// <summary>
        /// will return an array of token release dates if the user purchased in excess of the defined amounts
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public static object[] PublicTokensLocked(byte[] address)
        {
            StorageMap vestingData = Storage.CurrentContext.CreateMap(StorageKeys.VestedTokenPrefix());

            byte[] storedData = vestingData.Get(address);

            if (storedData.Length > 0)
            {
                return((object[])storedData.Deserialize());
            }
            return(new object[] { });
        }
Exemple #15
0
        /// <summary>
        /// retreive the balance of an address and show any tokens that are locked due to vesting
        /// </summary>
        /// <param name="account">address to check balance of</param>
        /// <returns>number of tokens</returns>
        public static BigInteger BalanceOfVestedAddress(byte[] account)
        {
            if (account.Length != 20)
            {
                Runtime.Log("BalanceOfVestedAddress() invalid address supplied");
                return(0);
            }

            StorageMap balances = Storage.CurrentContext.CreateMap(StorageKeys.VestedBalancePrefix());

            return(balances.Get(account).AsBigInteger());
        }
Exemple #16
0
        /// <summary>
        /// test if a contract address is a whitelisted TransferFrom
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public static bool IsContractWhitelistedTransferFrom(byte[] address)
        {
            if (IsTransferFromWhitelistingEnabled())
            {
                StorageMap TransferFromList = Storage.CurrentContext.CreateMap(StorageKeys.WhiteListedTransferFromList());

                bool isWhiteListed = TransferFromList.Get(address).AsString() == "1";
                Runtime.Notify("IsContractWhitelistedTransferFrom() address, isWhiteListed", address, isWhiteListed);
                return(isWhiteListed);
            }

            return(true);
        }
Exemple #17
0
        /// <summary>
        /// remove a DEX contract address from the whitelist
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public static bool WhitelistDEXRemove(byte[] address)
        {
            if (address.Length != 20)
            {
                return(false);
            }

            StorageMap dexList = Storage.CurrentContext.CreateMap(StorageKeys.WhiteListedDEXList());

            dexList.Delete(address);
            Runtime.Notify("WhitelistDEXRemove() removed contract from whitelist", address);

            return(true);
        }
        /// <summary>
        /// MintTokensEth is called when a the ETH contribution listener server triggers an Ether receive event
        /// </summary>
        /// <returns></returns>
        public static bool MintTokensEth(string ethAddress, byte[] neoAddress, ulong ethReceived)
        {
            object[]    transactionData = Helpers.GetEthTransactionAndSaleData(ethReceived, ethAddress, neoAddress);
            Transaction tx = (Transaction)transactionData[0];

            byte[]     sender                   = (byte[])transactionData[1];
            byte[]     receiver                 = (byte[])transactionData[2];
            BigInteger whiteListGroupNumber     = (BigInteger)transactionData[5];
            BigInteger crowdsaleAvailableAmount = (BigInteger)transactionData[6];
            BigInteger groupMaximumContribution = (BigInteger)transactionData[7];
            BigInteger totalTokensPurchased     = (BigInteger)transactionData[8] * NEP5.factor;
            BigInteger totalContributionBalance = (BigInteger)transactionData[9];

            if (!CanETHUserParticipateInSale(transactionData))
            {
                refundEth(ethAddress, ethReceived);
                Runtime.Notify("MintTokensEth() CanUserParticipate failed", false);
                return(false);
            }

            if (Helpers.GetBlockTimestamp() >= ICOTemplate.PublicSaleEndTime())
            {
                refundEth(ethAddress, ethReceived);
                Runtime.Notify("MintTokensEth() failed. Token Sale is closed.", false);
                return(false);
            }

            byte[] lastTransactionHash = Storage.Get(Storage.CurrentContext, StorageKeys.MintTokensEthLastTX());
            if (lastTransactionHash == tx.Hash)
            {
                // ensure that minTokens doesnt process the same transaction more than once
                Runtime.Notify("MintTokensEth() not processing duplicate tx.Hash", tx.Hash);
                return(false);
            }

            BigInteger tokenTotalSupply = NEP5.TotalSupply();

            Storage.Put(Storage.CurrentContext, StorageKeys.MintTokensEthLastTX(), tx.Hash);
            Runtime.Notify("MintTokensEth() receivedETH", ethReceived);

            BigInteger senderAmountSubjectToVesting = TokenSale.SubjectToVestingPeriod(sender);
            BigInteger newTokenBalance = NEP5.BalanceOf(sender) + totalTokensPurchased + senderAmountSubjectToVesting;

            Helpers.SetBalanceOf(sender, newTokenBalance);
            Helpers.SetBalanceOfSaleContribution(sender, totalContributionBalance);
            Helpers.SetTotalSupply(totalTokensPurchased);

            transfer(null, sender, totalTokensPurchased);
            return(true);
        }
Exemple #19
0
        /// <summary>
        /// add a DEX contract address to the whitelist
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public static bool WhitelistDEXAdd(byte[] address)
        {
            if (address.Length != 20)
            {
                return(false);
            }

            StorageMap dexList = Storage.CurrentContext.CreateMap(StorageKeys.WhiteListedDEXList());

            dexList.Put(address, "1");
            Runtime.Notify("WhitelistDEXAdd() added contract to whitelist", address);

            return(true);
        }
Exemple #20
0
        /// <summary>
        /// add an address to the kyc whitelist
        /// </summary>
        /// <param name="address"></param>
        public static bool AddAddress(byte[] address, int groupNumber)
        {
            if (address.Length != 20 || groupNumber <= 0)
            {
                return(false);
            }

            if (Helpers.VerifyIsAdminAccount())
            {
                StorageMap kycWhitelist = Storage.CurrentContext.CreateMap(StorageKeys.KYCWhitelistPrefix());
                kycWhitelist.Put(address, groupNumber);
                return(true);
            }
            return(false);
        }
Exemple #21
0
        /// <summary>
        /// remove an address from the whitelist
        /// </summary>
        /// <param name="address"></param>
        public static bool RevokeAddress(byte[] address)
        {
            if (address.Length != 20)
            {
                return(false);
            }

            if (Helpers.VerifyIsAdminAccount())
            {
                StorageMap kycWhitelist = Storage.CurrentContext.CreateMap(StorageKeys.KYCWhitelistPrefix());
                kycWhitelist.Delete(address);
                return(true);
            }
            return(false);
        }
Exemple #22
0
        /// <summary>
        /// remove an address from the whitelist
        /// </summary>
        /// <param name="address"></param>
        public static bool RevokeAddress(byte[] address)
        {
            if (address.Length != 20)
            {
                return(false);
            }

            if (Helpers.VerifyWitness(ICOTemplate.KycMiddlewareKey))
            {
                StorageMap kycWhitelist = Storage.CurrentContext.CreateMap(StorageKeys.KYCWhitelistPrefix());
                kycWhitelist.Delete(address);
                return(true);
            }
            return(false);
        }
Exemple #23
0
        /// <summary>
        /// add an address to the kyc whitelist
        /// </summary>
        /// <param name="address"></param>
        public static bool AddAddress(byte[] address, int groupNumber)
        {
            if (address.Length != 20 || groupNumber <= 0 || groupNumber > 4)
            {
                return(false);
            }

            if (Helpers.VerifyWitness(ICOTemplate.KycMiddlewareKey))
            {
                StorageMap kycWhitelist = Storage.CurrentContext.CreateMap(StorageKeys.KYCWhitelistPrefix());
                kycWhitelist.Put(address, groupNumber);
                return(true);
            }
            return(false);
        }
Exemple #24
0
        /// <summary>
        /// allow administrator to set the maximum contribution amount allowed for a presale group
        /// </summary>
        /// <param name="groupNumber"></param>
        /// <param name="maxContribution">max number of LX that can be purchased by this group</param>
        /// <returns></returns>
        public static bool SetGroupMaxContribution(BigInteger groupNumber, uint maxContribution)
        {
            if (groupNumber <= 0 || maxContribution <= 0)
            {
                return(false);
            }

            if (Helpers.VerifyIsAdminAccount())
            {
                StorageMap contributionLimits = Storage.CurrentContext.CreateMap(StorageKeys.GroupContributionAmountPrefix());
                contributionLimits.Put(groupNumber.AsByteArray(), maxContribution);
                return(true);
            }

            return(false);
        }
Exemple #25
0
        /// <summary>
        /// set a vesting schedule, as defined in the whitepaper, for tokens purchased during the presale
        /// </summary>
        /// <param name="address"></param>
        /// <param name="tokenBalance"></param>
        /// <returns></returns>
        public static bool SetVestingPeriodForAddress(byte[] address, BigInteger tokensPurchased)
        {
            if (!ICOTemplate.UseTokenVestingPeriod())
            {
                return(false);
            }

            if (address.Length != 20)
            {
                return(false);
            }

            object[]   vestingOne              = ICOTemplate.VestingBracketOne();
            object[]   vestingTwo              = ICOTemplate.VestingBracketTwo();
            BigInteger bracketOneThreshold     = (BigInteger)vestingOne[0] * NEP5.factor;
            BigInteger bracketTwoThreshold     = (BigInteger)vestingTwo[0] * NEP5.factor;
            BigInteger currentAvailableBalance = 0;        // how many tokens will be immediately available to the owner

            uint       currentTimestamp      = Helpers.GetContractInitTime();
            uint       bracketOneReleaseDate = (uint)vestingOne[1] + currentTimestamp;
            uint       bracketTwoReleaseDate = (uint)vestingTwo[1] + currentTimestamp;
            StorageMap vestingData           = Storage.CurrentContext.CreateMap(StorageKeys.VestedTokenPrefix());

            if (tokensPurchased > bracketTwoThreshold)
            {
                // user has purchased enough tokens to fall under the second vesting period restriction
                // calculate the difference between the bracketOne and bracketTwo thresholds to calculate how much should be released after bracketOne lapses
                BigInteger bracketOneReleaseAmount = bracketTwoThreshold - bracketOneThreshold;
                // the remainder will be released after the bracket two release date
                BigInteger bracketTwoReleaseAmount = tokensPurchased - bracketOneReleaseAmount - bracketOneThreshold;
                object[]   lockoutTimes            = new object[] { bracketOneReleaseDate, bracketOneReleaseAmount, bracketTwoReleaseDate, bracketTwoReleaseAmount };
                vestingData.Put(address, lockoutTimes.Serialize());
            }
            else
            {
                // user has purchased enough tokens to fall under the first vesting period restriction
                // calculate the difference between amount purchased and bracketOne threshold to calculate how much should be released after the bracketOne lapses
                BigInteger bracketOneReleaseAmount = tokensPurchased - bracketOneThreshold;
                object[]   lockoutTimes            = new object[] { bracketOneReleaseDate, bracketOneReleaseAmount };
                vestingData.Put(address, lockoutTimes.Serialize());
            }

            // ensure the total amount purchased is saved
            Helpers.SetBalanceOf(address, tokensPurchased);
            Helpers.SetBalanceOfVestedAmount(address, tokensPurchased);
            return(true);
        }
Exemple #26
0
        /// <summary>
        /// initialise the smart contract for use
        /// </summary>
        /// <returns></returns>
        public static bool InitSmartContract()
        {
            if (Helpers.ContractInitialised())
            {
                // contract can only be initialised once
                Runtime.Log("InitSmartContract() contract already initialised");
                return(false);
            }

            uint ContractInitTime = Helpers.GetBlockTimestamp();

            Storage.Put(Storage.CurrentContext, StorageKeys.ContractInitTime(), ContractInitTime);

            // assign pre-allocated tokens to the project
            object[] immediateAllocation = ICOContract.ImmediateProjectGrowthAllocation();
            object[] vestedAllocation    = ICOContract.VestedProjectGrowthAllocation();

            BigInteger immediateProjectAllocationValue = ((ICOContract.TokenMaxSupply * (BigInteger)immediateAllocation[0]) / 100) * NEP5.factor;
            BigInteger vestedProjectAllocationValue    = ((ICOContract.TokenMaxSupply * (BigInteger)vestedAllocation[0]) / 100) * NEP5.factor;

            Helpers.SetBalanceOf(ICOContract.MoonlightProjectKey(), immediateProjectAllocationValue + vestedProjectAllocationValue);
            Helpers.SetBalanceOfVestedAmount(ICOContract.MoonlightProjectKey(), immediateProjectAllocationValue + vestedProjectAllocationValue);

            // lockup a portion of the tokens to be released in the future
            uint vestedGrowthReleaseDate = (uint)vestedAllocation[1] + ContractInitTime;

            object[]   vestedTokenPeriod = new object[] { vestedGrowthReleaseDate, vestedProjectAllocationValue };
            StorageMap vestingData       = Storage.CurrentContext.CreateMap(StorageKeys.VestedTokenPrefix());

            vestingData.Put(ICOContract.MoonlightProjectKey(), vestedTokenPeriod.Serialize());

            // token allocation to MoonlightFounderKeys - update the total supply to include balance - these funds will be unlocked gradually
            BigInteger founderTokenAllocation = ((ICOContract.TokenMaxSupply * (BigInteger)ICOContract.MoonlightFoundersAllocationPercentage()) / 100) * NEP5.factor;

            // token allocated to presale
            BigInteger presaleAllocationMaxValue = ((ICOContract.TokenMaxSupply * (BigInteger)ICOContract.PresaleAllocationPercentage()) / 100) * NEP5.factor;

            // update the total supply to reflect the project allocated tokens
            BigInteger totalSupply = immediateProjectAllocationValue + vestedProjectAllocationValue + founderTokenAllocation + presaleAllocationMaxValue;

            Helpers.SetTotalSupply(totalSupply);

            UpdateAdminAddress(ICOContract.InitialAdminAccount);
            EnableDEXWhitelisting(ICOContract.WhitelistDEXListings());
            Runtime.Log("InitSmartContract() contract initialisation complete");
            return(true);
        }
Exemple #27
0
        /// <summary>
        /// set the block number that a specific group is allowed to participate in the ICO
        /// </summary>
        /// <param name="groupNumber"></param>
        /// <param name="unlockBlockNumber">group will be able to participate at this block height</param>
        /// <returns></returns>
        public static bool SetGroupUnlockBlock(BigInteger groupNumber, uint unlockBlockNumber)
        {
            if (groupNumber <= 0 || unlockBlockNumber <= 0)
            {
                return(false);
            }

            if (Helpers.VerifyIsAdminAccount())
            {
                Runtime.Notify("SetGroupUnlockBlock() groupNumber / unlockBlockNumber", groupNumber, unlockBlockNumber);
                StorageMap unlockBlocks = Storage.CurrentContext.CreateMap(StorageKeys.GroupUnlockPrefix());
                unlockBlocks.Put(groupNumber.AsByteArray(), unlockBlockNumber);
                return(true);
            }

            return(false);
        }
Exemple #28
0
        public static object HandleHelperOperation(string operation, params object[] args)
        {
            switch (operation)
            {
            case "BalanceOfVestedAddress":
                if (!Helpers.RequireArgumentLength(args, 1))
                {
                    return(false);
                }
                return(Helpers.BalanceOfVestedAddress((byte[])args[0]));

            case "IsPresaleAllocationLocked":
                return(Storage.Get(Storage.CurrentContext, StorageKeys.PresaleAllocationLocked()));

            case "supportedStandards":
                return(DIVE.DIVE.supportedStandards());
            }
            return(false);
        }
Exemple #29
0
        /// <summary>
        /// update the balance of an address to include any tokens subject to a vesting period
        /// </summary>
        /// <param name="address"></param>
        /// <param name="newBalance"></param>
        public static void SetBalanceOfVestedAmount(byte[] address, BigInteger newBalance, string allocationType)
        {
            if (address.Length != 20)
            {
                Runtime.Log("SetBalanceOfVestedAmount() address.length != 20");
                return;
            }

            StorageMap balances = Storage.CurrentContext.CreateMap(StorageKeys.VestedBalancePrefix());

            if (newBalance <= 0)
            {
                balances.Delete(address);
            }
            else
            {
                Runtime.Notify("SetBalanceOfVestedAmount() setting balance", newBalance, allocationType);
                balances.Put(address, newBalance);
            }
        }
Exemple #30
0
        public static BigInteger BalanceOf(byte[] account)
        {
            if (account.Length != 20)
            {
                Runtime.Log("BalanceOf() invalid address supplied");
                return(0);
            }

            StorageMap balances = Storage.CurrentContext.CreateMap(StorageKeys.BalancePrefix());

            BigInteger amountSubjectToVesting = TokenSale.SubjectToVestingPeriod(account);
            BigInteger userBalance            = balances.Get(account).AsBigInteger() - amountSubjectToVesting;

            if (userBalance < 0)
            {
                userBalance = 0;
            }

            return(userBalance.AsByteArray().Concat(new byte[] { }).AsBigInteger());
        }