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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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()); }
/// <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)); } }
/// <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()); }
/// <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()); }
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()); }
/// <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[] { }); }
/// <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()); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
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); }
/// <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); } }
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()); }