@leofcoin/contracts 0.1.11 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.prettierrc CHANGED
@@ -2,7 +2,10 @@
2
2
  "tabWidth": 2,
3
3
  "semi": false,
4
4
  "singleQuote": true,
5
- "printWidth": 120,
5
+ "printWidth": 100,
6
+ "bracketSpacing": true,
6
7
  "trailingComma": "none",
7
- "bracketSameLine": true
8
+ "bracketSameLine": true,
9
+ "arrowParens": "always",
10
+ "singleAttributePerLine": true
8
11
  }
@@ -0,0 +1,12 @@
1
+ import { TokenReceiver } from '@leofcoin/standards';
2
+ import { TokenReceiverState } from '@leofcoin/standards/token-receiver';
3
+ export interface chatState extends TokenReceiverState {
4
+ nicknames: {
5
+ [address: string]: string;
6
+ };
7
+ }
8
+ export default class Chat extends TokenReceiver {
9
+ #private;
10
+ constructor(tokenToReceive: any, tokenAmountToReceive: any, state: any);
11
+ changeNickName(newName: string): Promise<void>;
12
+ }
@@ -3,15 +3,15 @@ import type { PublicVotingState } from '@leofcoin/standards/public-voting';
3
3
  import { TokenReceiverState } from '@leofcoin/standards/token-receiver';
4
4
  export interface FactoryState extends TokenReceiverState {
5
5
  contracts: any[];
6
- totalContracts: typeof BigNumber;
6
+ totalContracts: bigint;
7
7
  }
8
8
  export default class Factory extends TokenReceiver {
9
9
  #private;
10
- constructor(tokenToReceive: address, tokenAmountToReceive: typeof BigNumber, state: FactoryState);
10
+ constructor(tokenToReceive: address, tokenAmountToReceive: bigint, state: FactoryState);
11
11
  get state(): PublicVotingState;
12
12
  get name(): string;
13
13
  get contracts(): string[];
14
- get totalContracts(): import("@ethersproject/bignumber").BigNumber;
14
+ get totalContracts(): bigint;
15
15
  isRegistered(address: any): boolean;
16
16
  /**
17
17
  *
@@ -1 +1 @@
1
- class ContractCreator{#creator;constructor(state){this.#creator=state?state.contractCreator:msg.sender}get _contractCreator(){return this.#creator}get state(){return{contractCreator:this.#creator}}get _isContractCreator(){return msg.sender===this.#creator}}class Voting extends ContractCreator{#votes={};#votingDisabled=!1;#votingDuration=1728e5;constructor(state){super(state),state&&(this.#votes=state.votes,this.#votingDisabled=state.votingDisabled,this.#votingDuration=state.votingDuration)}get votes(){return{...this.#votes}}get votingDuration(){return this.#votingDuration}get votingDisabled(){return this.#votingDisabled}get state(){return{...super.state,votes:this.#votes,votingDisabled:this.#votingDisabled,votingDuration:this.#votingDuration}}#canVote(){return this._canVote?.()}#beforeVote(){return this._beforeVote?.()}#afterVote(){return this._afterVote?.()}createVote(title,description,endTime,method,args=[]){if(!this.#canVote())throw new Error("Not allowed to create a vote");const id=crypto.randomUUID();this.#votes[id]={title:title,description:description,method:method,endTime:endTime,args:args}}#endVoting(voteId){let agree=Object.values(this.#votes[voteId].results).filter((result=>1===result)),disagree=Object.values(this.#votes[voteId].results).filter((result=>0===result));agree.length>disagree.length&&this[this.#votes[voteId].method](...this.#votes[voteId].args),this.#votes[voteId].finished=!0}async vote(voteId,vote){if(0!==(vote=Number(vote))&&.5!==vote&&1!==vote)throw new Error(`invalid vote value ${vote}`);if(!this.#votes[voteId])throw new Error(`Nothing found for ${voteId}`);const ended=(new Date).getTime()>this.#votes[voteId].endTime;if(ended&&!this.#votes[voteId].finished&&this.#endVoting(voteId),ended)throw new Error("voting already ended");if(!this.#canVote())throw new Error("Not allowed to vote");await this.#beforeVote(),this.#votes[voteId][msg.sender]=vote,await this.#afterVote()}get votesInProgress(){return Object.entries(this.#votes).filter((([id,vote])=>!vote.finished)).map((([id,vote])=>({...vote,id:id})))}#disableVoting(){this.#votingDisabled=!0}disableVoting(){if(!this.#canVote())throw new Error("not a allowed");this.createVote("disable voting","Warning this disables all voting features forever",(new Date).getTime()+this.#votingDuration,"#disableVoting",[])}sync(){for(const vote of this.votesInProgress)vote.endTime<(new Date).getTime()&&this.#endVoting(vote.id)}}class PublicVoting extends Voting{constructor(state){super(state)}}class TokenReceiver extends PublicVoting{#tokenToReceive;#tokenAmountToReceive;#tokenReceiver;#voteType="transfer";constructor(tokenToReceive,tokenAmountToReceive,burns,state){super(state),state?(this.#tokenReceiver=state.tokenReceiver,this.#tokenToReceive=state.tokenToReceive,this.#tokenAmountToReceive=BigNumber.from(state.tokenAmountToReceive),this.#voteType=state.voteType):(this.#tokenReceiver=msg.contract,this.#tokenToReceive=tokenToReceive,this.#tokenAmountToReceive=BigNumber.from(tokenAmountToReceive),burns&&(this.#voteType="burn"))}get tokenToReceive(){return this.#tokenToReceive}get tokenAmountToReceive(){return this.#tokenAmountToReceive}get tokenReceiver(){return this.#tokenReceiver}get state(){return{...super.state,tokenReceiver:this.#tokenReceiver,tokenToReceive:this.#tokenToReceive,tokenAmountToReceive:this.#tokenAmountToReceive,voteType:this.#voteType}}async#canVote(){return(await msg.staticCall(this.#tokenToReceive,"balanceOf",[msg.sender])).gte(this.#tokenAmountToReceive)}async _canVote(){return this.#canVote()}async#beforeVote(){return"burn"===this.#voteType?msg.staticCall(this.tokenToReceive,"burn",[this.tokenAmountToReceive]):msg.staticCall(this.tokenToReceive,"transfer",[msg.sender,this.tokenReceiver,this.tokenAmountToReceive])}async _beforeVote(){return this.#beforeVote()}async _payTokenToReceive(){return msg.staticCall(this.#tokenToReceive,"transfer",[msg.sender,this.#tokenReceiver,this.#tokenAmountToReceive])}async _burnTokenToReceive(){return msg.staticCall(this.#tokenToReceive,"burn",[this.#tokenAmountToReceive])}async _canPay(){return(await msg.call(this.#tokenToReceive,"balance",[])).gte(this.tokenAmountToReceive)}#changeTokenToReceive(address){this.#tokenToReceive=address}#changeTokenAmountToReceive(amount){this.#tokenAmountToReceive=amount}#changeVoteType(type){this.#voteType=type}#getTokensOut(amount,receiver){return msg.call(this.#tokenReceiver,"transfer",[this.#tokenReceiver,receiver,amount])}async changeVoteType(type){if(!this.#canVote())throw new Error("not a allowed");if("transfer"===this.#voteType&&(await this.#balance()).gt(0))throw new Error("get tokens out first or they be lost forever");this.createVote("change the token amount to receive","set tokenAmountToReceive",(new Date).getTime()+this.votingDuration,"#changeVoteType",[type])}getTokensOut(amount,receiver){if(!this.#canVote())throw new Error("not a allowed");this.createVote("withdraw all tokens",`withdraw all tokens to ${receiver}`,(new Date).getTime()+this.votingDuration,"#getTokensOut",[amount,receiver])}changeTokenAmountToReceive(){if(!this.#canVote())throw new Error("not a allowed");this.createVote("change the token amount to receive","set tokenAmountToReceive",(new Date).getTime()+this.votingDuration,"#changeTokenAmountToReceive",[])}#balance(){return msg.staticCall(this.#tokenToReceive,"balanceOf",[this.#tokenReceiver])}async changeTokenToReceive(){if(!this.#canVote())throw new Error("not a allowed");if(!(await this.#balance()).eq(0)&&"transfer"===this.#voteType)throw new Error("get tokens out first or they be lost forever");this.createVote("change the token to receive","set tokenToReceive to a new address",(new Date).getTime()+this.votingDuration,"#changeTokenToReceive",[])}}class Factory extends TokenReceiver{#name="LeofcoinContractFactory";#totalContracts=BigNumber.from(0);#contracts=[];constructor(tokenToReceive,tokenAmountToReceive,state){super(tokenToReceive,tokenAmountToReceive,!0,state),state&&(this.#contracts=state.contracts,this.#totalContracts=state.totalContracts)}get state(){return{...super.state,totalContracts:this.#totalContracts,contracts:this.#contracts}}get name(){return this.#name}get contracts(){return[...this.#contracts]}get totalContracts(){return this.#totalContracts}isRegistered(address){return this.#contracts.includes(address)}#isCreator(address){return msg.staticCall(address,"_isContractCreator")}async registerContract(address){if(!this._canPay())throw new Error("can't register, balance to low");if(!await this.#isCreator(address))throw new Error("You don't own that contract");if(this.#contracts.includes(address))throw new Error("already registered");await this._payTokenToReceive(),this.#totalContracts.add(1),this.#contracts.push(address)}}export{Factory as default};
1
+ class ContractCreator{#creator;constructor(state){this.#creator=state?state.contractCreator:msg.sender}get _contractCreator(){return this.#creator}get state(){return{contractCreator:this.#creator}}get _isContractCreator(){return msg.sender===this.#creator}}class Voting extends ContractCreator{#votes={};#votingDisabled=!1;#votingDuration=1728e5;constructor(state){super(state),state&&(this.#votes=state.votes,this.#votingDisabled=state.votingDisabled,this.#votingDuration=state.votingDuration)}get votes(){return{...this.#votes}}get votingDuration(){return this.#votingDuration}get votingDisabled(){return this.#votingDisabled}get state(){return{...super.state,votes:this.#votes,votingDisabled:this.#votingDisabled,votingDuration:this.#votingDuration}}#canVote(){return this._canVote?.()}#beforeVote(){return this._beforeVote?.()}#afterVote(){return this._afterVote?.()}createVote(title,description,endTime,method,args=[]){if(!this.#canVote())throw new Error("Not allowed to create a vote");const id=crypto.randomUUID();this.#votes[id]={title:title,description:description,method:method,endTime:endTime,args:args}}#endVoting(voteId){let agree=Object.values(this.#votes[voteId].results).filter((result=>1===result)),disagree=Object.values(this.#votes[voteId].results).filter((result=>0===result));agree.length>disagree.length&&this[this.#votes[voteId].method](...this.#votes[voteId].args),this.#votes[voteId].finished=!0}async vote(voteId,vote){if(0!==(vote=Number(vote))&&.5!==vote&&1!==vote)throw new Error(`invalid vote value ${vote}`);if(!this.#votes[voteId])throw new Error(`Nothing found for ${voteId}`);const ended=(new Date).getTime()>this.#votes[voteId].endTime;if(ended&&!this.#votes[voteId].finished&&this.#endVoting(voteId),ended)throw new Error("voting already ended");if(!this.#canVote())throw new Error("Not allowed to vote");await this.#beforeVote(),this.#votes[voteId][msg.sender]=vote,await this.#afterVote()}get votesInProgress(){return Object.entries(this.#votes).filter((([id,vote])=>!vote.finished)).map((([id,vote])=>({...vote,id:id})))}#disableVoting(){this.#votingDisabled=!0}disableVoting(){if(!this.#canVote())throw new Error("not a allowed");this.createVote("disable voting","Warning this disables all voting features forever",(new Date).getTime()+this.#votingDuration,"#disableVoting",[])}sync(){for(const vote of this.votesInProgress)vote.endTime<(new Date).getTime()&&this.#endVoting(vote.id)}}class PublicVoting extends Voting{constructor(state){super(state)}}class TokenReceiver extends PublicVoting{#tokenToReceive;#tokenAmountToReceive;#tokenReceiver;#voteType="transfer";constructor(tokenToReceive,tokenAmountToReceive,burns,state){super(state),state?(this.#tokenReceiver=state.tokenReceiver,this.#tokenToReceive=state.tokenToReceive,this.#tokenAmountToReceive=BigInt(state.tokenAmountToReceive),this.#voteType=state.voteType):(this.#tokenReceiver=msg.contract,this.#tokenToReceive=tokenToReceive,this.#tokenAmountToReceive=BigInt(tokenAmountToReceive),burns&&(this.#voteType="burn"))}get tokenToReceive(){return this.#tokenToReceive}get tokenAmountToReceive(){return this.#tokenAmountToReceive}get tokenReceiver(){return this.#tokenReceiver}get state(){return{...super.state,tokenReceiver:this.#tokenReceiver,tokenToReceive:this.#tokenToReceive,tokenAmountToReceive:this.#tokenAmountToReceive,voteType:this.#voteType}}async#canVote(){return await msg.staticCall(this.#tokenToReceive,"balanceOf",[msg.sender])>=this.#tokenAmountToReceive}async _canVote(){return this.#canVote()}async#beforeVote(){return"burn"===this.#voteType?msg.staticCall(this.tokenToReceive,"burn",[this.tokenAmountToReceive]):msg.staticCall(this.tokenToReceive,"transfer",[msg.sender,this.tokenReceiver,this.tokenAmountToReceive])}async _beforeVote(){return this.#beforeVote()}async _payTokenToReceive(){return msg.staticCall(this.#tokenToReceive,"transfer",[msg.sender,this.#tokenReceiver,this.#tokenAmountToReceive])}async _burnTokenToReceive(){return msg.staticCall(this.#tokenToReceive,"burn",[this.#tokenAmountToReceive])}async _canPay(){return(await msg.call(this.#tokenToReceive,"balance",[])).gte(this.tokenAmountToReceive)}#changeTokenToReceive(address){this.#tokenToReceive=address}#changeTokenAmountToReceive(amount){this.#tokenAmountToReceive=amount}#changeVoteType(type){this.#voteType=type}#getTokensOut(amount,receiver){return msg.call(this.#tokenReceiver,"transfer",[this.#tokenReceiver,receiver,amount])}async changeVoteType(type){if(!this.#canVote())throw new Error("not a allowed");if("transfer"===this.#voteType&&await this.#balance()>0n)throw new Error("get tokens out first or they be lost forever");this.createVote("change the token amount to receive","set tokenAmountToReceive",(new Date).getTime()+this.votingDuration,"#changeVoteType",[type])}getTokensOut(amount,receiver){if(!this.#canVote())throw new Error("not a allowed");this.createVote("withdraw all tokens",`withdraw all tokens to ${receiver}`,(new Date).getTime()+this.votingDuration,"#getTokensOut",[amount,receiver])}changeTokenAmountToReceive(){if(!this.#canVote())throw new Error("not a allowed");this.createVote("change the token amount to receive","set tokenAmountToReceive",(new Date).getTime()+this.votingDuration,"#changeTokenAmountToReceive",[])}#balance(){return msg.staticCall(this.#tokenToReceive,"balanceOf",[this.#tokenReceiver])}async changeTokenToReceive(){if(!this.#canVote())throw new Error("not a allowed");if(await this.#balance()>0n&&"transfer"===this.#voteType)throw new Error("get tokens out first or they be lost forever");this.createVote("change the token to receive","set tokenToReceive to a new address",(new Date).getTime()+this.votingDuration,"#changeTokenToReceive",[])}}class Factory extends TokenReceiver{#name="LeofcoinContractFactory";#totalContracts=BigInt(0);#contracts=[];constructor(tokenToReceive,tokenAmountToReceive,state){super(tokenToReceive,tokenAmountToReceive,!0,state),state&&(this.#contracts=state.contracts,this.#totalContracts=state.totalContracts)}get state(){return{...super.state,totalContracts:this.#totalContracts,contracts:this.#contracts}}get name(){return this.#name}get contracts(){return[...this.#contracts]}get totalContracts(){return this.#totalContracts}isRegistered(address){return this.#contracts.includes(address)}#isCreator(address){return msg.staticCall(address,"_isContractCreator")}async registerContract(address){if(!this._canPay())throw new Error("can't register, balance to low");if(!await this.#isCreator(address))throw new Error("You don't own that contract");if(this.#contracts.includes(address))throw new Error("already registered");await this._payTokenToReceive(),this.#totalContracts+=1n,this.#contracts.push(address)}}export{Factory as default};
@@ -14,7 +14,7 @@ export default class NameService extends TokenReceiver {
14
14
  get name(): string;
15
15
  get registry(): {};
16
16
  get state(): NameServiceState;
17
- constructor(factoryAddress: address, tokenToReceive: address, validatorAddress: address, tokenAmountToReceive: typeof BigNumber, state: NameServiceState);
17
+ constructor(factoryAddress: address, tokenToReceive: address, validatorAddress: address, tokenAmountToReceive: bigint, state: NameServiceState);
18
18
  purchaseName(name: string | number, address: any): Promise<void>;
19
19
  lookup(name: string | number): any;
20
20
  transferOwnership(name: string | number, to: any): void;
@@ -1 +1 @@
1
- class ContractCreator{#creator;constructor(state){this.#creator=state?state.contractCreator:msg.sender}get _contractCreator(){return this.#creator}get state(){return{contractCreator:this.#creator}}get _isContractCreator(){return msg.sender===this.#creator}}class Voting extends ContractCreator{#votes={};#votingDisabled=!1;#votingDuration=1728e5;constructor(state){super(state),state&&(this.#votes=state.votes,this.#votingDisabled=state.votingDisabled,this.#votingDuration=state.votingDuration)}get votes(){return{...this.#votes}}get votingDuration(){return this.#votingDuration}get votingDisabled(){return this.#votingDisabled}get state(){return{...super.state,votes:this.#votes,votingDisabled:this.#votingDisabled,votingDuration:this.#votingDuration}}#canVote(){return this._canVote?.()}#beforeVote(){return this._beforeVote?.()}#afterVote(){return this._afterVote?.()}createVote(title,description,endTime,method,args=[]){if(!this.#canVote())throw new Error("Not allowed to create a vote");const id=crypto.randomUUID();this.#votes[id]={title:title,description:description,method:method,endTime:endTime,args:args}}#endVoting(voteId){let agree=Object.values(this.#votes[voteId].results).filter((result=>1===result)),disagree=Object.values(this.#votes[voteId].results).filter((result=>0===result));agree.length>disagree.length&&this[this.#votes[voteId].method](...this.#votes[voteId].args),this.#votes[voteId].finished=!0}async vote(voteId,vote){if(0!==(vote=Number(vote))&&.5!==vote&&1!==vote)throw new Error(`invalid vote value ${vote}`);if(!this.#votes[voteId])throw new Error(`Nothing found for ${voteId}`);const ended=(new Date).getTime()>this.#votes[voteId].endTime;if(ended&&!this.#votes[voteId].finished&&this.#endVoting(voteId),ended)throw new Error("voting already ended");if(!this.#canVote())throw new Error("Not allowed to vote");await this.#beforeVote(),this.#votes[voteId][msg.sender]=vote,await this.#afterVote()}get votesInProgress(){return Object.entries(this.#votes).filter((([id,vote])=>!vote.finished)).map((([id,vote])=>({...vote,id:id})))}#disableVoting(){this.#votingDisabled=!0}disableVoting(){if(!this.#canVote())throw new Error("not a allowed");this.createVote("disable voting","Warning this disables all voting features forever",(new Date).getTime()+this.#votingDuration,"#disableVoting",[])}sync(){for(const vote of this.votesInProgress)vote.endTime<(new Date).getTime()&&this.#endVoting(vote.id)}}class PublicVoting extends Voting{constructor(state){super(state)}}class TokenReceiver extends PublicVoting{#tokenToReceive;#tokenAmountToReceive;#tokenReceiver;#voteType="transfer";constructor(tokenToReceive,tokenAmountToReceive,burns,state){super(state),state?(this.#tokenReceiver=state.tokenReceiver,this.#tokenToReceive=state.tokenToReceive,this.#tokenAmountToReceive=BigNumber.from(state.tokenAmountToReceive),this.#voteType=state.voteType):(this.#tokenReceiver=msg.contract,this.#tokenToReceive=tokenToReceive,this.#tokenAmountToReceive=BigNumber.from(tokenAmountToReceive),burns&&(this.#voteType="burn"))}get tokenToReceive(){return this.#tokenToReceive}get tokenAmountToReceive(){return this.#tokenAmountToReceive}get tokenReceiver(){return this.#tokenReceiver}get state(){return{...super.state,tokenReceiver:this.#tokenReceiver,tokenToReceive:this.#tokenToReceive,tokenAmountToReceive:this.#tokenAmountToReceive,voteType:this.#voteType}}async#canVote(){return(await msg.staticCall(this.#tokenToReceive,"balanceOf",[msg.sender])).gte(this.#tokenAmountToReceive)}async _canVote(){return this.#canVote()}async#beforeVote(){return"burn"===this.#voteType?msg.staticCall(this.tokenToReceive,"burn",[this.tokenAmountToReceive]):msg.staticCall(this.tokenToReceive,"transfer",[msg.sender,this.tokenReceiver,this.tokenAmountToReceive])}async _beforeVote(){return this.#beforeVote()}async _payTokenToReceive(){return msg.staticCall(this.#tokenToReceive,"transfer",[msg.sender,this.#tokenReceiver,this.#tokenAmountToReceive])}async _burnTokenToReceive(){return msg.staticCall(this.#tokenToReceive,"burn",[this.#tokenAmountToReceive])}async _canPay(){return(await msg.call(this.#tokenToReceive,"balance",[])).gte(this.tokenAmountToReceive)}#changeTokenToReceive(address){this.#tokenToReceive=address}#changeTokenAmountToReceive(amount){this.#tokenAmountToReceive=amount}#changeVoteType(type){this.#voteType=type}#getTokensOut(amount,receiver){return msg.call(this.#tokenReceiver,"transfer",[this.#tokenReceiver,receiver,amount])}async changeVoteType(type){if(!this.#canVote())throw new Error("not a allowed");if("transfer"===this.#voteType&&(await this.#balance()).gt(0))throw new Error("get tokens out first or they be lost forever");this.createVote("change the token amount to receive","set tokenAmountToReceive",(new Date).getTime()+this.votingDuration,"#changeVoteType",[type])}getTokensOut(amount,receiver){if(!this.#canVote())throw new Error("not a allowed");this.createVote("withdraw all tokens",`withdraw all tokens to ${receiver}`,(new Date).getTime()+this.votingDuration,"#getTokensOut",[amount,receiver])}changeTokenAmountToReceive(){if(!this.#canVote())throw new Error("not a allowed");this.createVote("change the token amount to receive","set tokenAmountToReceive",(new Date).getTime()+this.votingDuration,"#changeTokenAmountToReceive",[])}#balance(){return msg.staticCall(this.#tokenToReceive,"balanceOf",[this.#tokenReceiver])}async changeTokenToReceive(){if(!this.#canVote())throw new Error("not a allowed");if(!(await this.#balance()).eq(0)&&"transfer"===this.#voteType)throw new Error("get tokens out first or they be lost forever");this.createVote("change the token to receive","set tokenToReceive to a new address",(new Date).getTime()+this.votingDuration,"#changeTokenToReceive",[])}}class NameService extends TokenReceiver{#name="LeofcoinNameService";#registry={};get name(){return this.#name}get registry(){return{...this.#registry}}get state(){return{...super.state,registry:this.#registry}}constructor(factoryAddress,tokenToReceive,validatorAddress,tokenAmountToReceive,state){super(tokenToReceive,tokenAmountToReceive,!0,state),state?this.#registry=state.registry:(this.#registry.LeofcoinContractFactory={owner:msg.sender,address:factoryAddress},this.#registry.LeofcoinToken={owner:msg.sender,address:tokenToReceive},this.#registry.LeofcoinValidators={owner:msg.sender,address:validatorAddress})}async purchaseName(name,address){await this._canPay(),await this._payTokenToReceive(),this.#registry[name]={owner:msg.sender,address:address}}lookup(name){return this.#registry[name]}transferOwnership(name,to){if(msg.sender!==this.#registry[name].owner)throw new Error("not allowed");this.#registry[name].owner=to}changeAddress(name,address){if(msg.sender!==this.#registry[name].owner)throw new Error("not allowed");this.#registry[name].address=address}}export{NameService as default};
1
+ class ContractCreator{#creator;constructor(state){this.#creator=state?state.contractCreator:msg.sender}get _contractCreator(){return this.#creator}get state(){return{contractCreator:this.#creator}}get _isContractCreator(){return msg.sender===this.#creator}}class Voting extends ContractCreator{#votes={};#votingDisabled=!1;#votingDuration=1728e5;constructor(state){super(state),state&&(this.#votes=state.votes,this.#votingDisabled=state.votingDisabled,this.#votingDuration=state.votingDuration)}get votes(){return{...this.#votes}}get votingDuration(){return this.#votingDuration}get votingDisabled(){return this.#votingDisabled}get state(){return{...super.state,votes:this.#votes,votingDisabled:this.#votingDisabled,votingDuration:this.#votingDuration}}#canVote(){return this._canVote?.()}#beforeVote(){return this._beforeVote?.()}#afterVote(){return this._afterVote?.()}createVote(title,description,endTime,method,args=[]){if(!this.#canVote())throw new Error("Not allowed to create a vote");const id=crypto.randomUUID();this.#votes[id]={title:title,description:description,method:method,endTime:endTime,args:args}}#endVoting(voteId){let agree=Object.values(this.#votes[voteId].results).filter((result=>1===result)),disagree=Object.values(this.#votes[voteId].results).filter((result=>0===result));agree.length>disagree.length&&this[this.#votes[voteId].method](...this.#votes[voteId].args),this.#votes[voteId].finished=!0}async vote(voteId,vote){if(0!==(vote=Number(vote))&&.5!==vote&&1!==vote)throw new Error(`invalid vote value ${vote}`);if(!this.#votes[voteId])throw new Error(`Nothing found for ${voteId}`);const ended=(new Date).getTime()>this.#votes[voteId].endTime;if(ended&&!this.#votes[voteId].finished&&this.#endVoting(voteId),ended)throw new Error("voting already ended");if(!this.#canVote())throw new Error("Not allowed to vote");await this.#beforeVote(),this.#votes[voteId][msg.sender]=vote,await this.#afterVote()}get votesInProgress(){return Object.entries(this.#votes).filter((([id,vote])=>!vote.finished)).map((([id,vote])=>({...vote,id:id})))}#disableVoting(){this.#votingDisabled=!0}disableVoting(){if(!this.#canVote())throw new Error("not a allowed");this.createVote("disable voting","Warning this disables all voting features forever",(new Date).getTime()+this.#votingDuration,"#disableVoting",[])}sync(){for(const vote of this.votesInProgress)vote.endTime<(new Date).getTime()&&this.#endVoting(vote.id)}}class PublicVoting extends Voting{constructor(state){super(state)}}class TokenReceiver extends PublicVoting{#tokenToReceive;#tokenAmountToReceive;#tokenReceiver;#voteType="transfer";constructor(tokenToReceive,tokenAmountToReceive,burns,state){super(state),state?(this.#tokenReceiver=state.tokenReceiver,this.#tokenToReceive=state.tokenToReceive,this.#tokenAmountToReceive=BigInt(state.tokenAmountToReceive),this.#voteType=state.voteType):(this.#tokenReceiver=msg.contract,this.#tokenToReceive=tokenToReceive,this.#tokenAmountToReceive=BigInt(tokenAmountToReceive),burns&&(this.#voteType="burn"))}get tokenToReceive(){return this.#tokenToReceive}get tokenAmountToReceive(){return this.#tokenAmountToReceive}get tokenReceiver(){return this.#tokenReceiver}get state(){return{...super.state,tokenReceiver:this.#tokenReceiver,tokenToReceive:this.#tokenToReceive,tokenAmountToReceive:this.#tokenAmountToReceive,voteType:this.#voteType}}async#canVote(){return await msg.staticCall(this.#tokenToReceive,"balanceOf",[msg.sender])>=this.#tokenAmountToReceive}async _canVote(){return this.#canVote()}async#beforeVote(){return"burn"===this.#voteType?msg.staticCall(this.tokenToReceive,"burn",[this.tokenAmountToReceive]):msg.staticCall(this.tokenToReceive,"transfer",[msg.sender,this.tokenReceiver,this.tokenAmountToReceive])}async _beforeVote(){return this.#beforeVote()}async _payTokenToReceive(){return msg.staticCall(this.#tokenToReceive,"transfer",[msg.sender,this.#tokenReceiver,this.#tokenAmountToReceive])}async _burnTokenToReceive(){return msg.staticCall(this.#tokenToReceive,"burn",[this.#tokenAmountToReceive])}async _canPay(){return(await msg.call(this.#tokenToReceive,"balance",[])).gte(this.tokenAmountToReceive)}#changeTokenToReceive(address){this.#tokenToReceive=address}#changeTokenAmountToReceive(amount){this.#tokenAmountToReceive=amount}#changeVoteType(type){this.#voteType=type}#getTokensOut(amount,receiver){return msg.call(this.#tokenReceiver,"transfer",[this.#tokenReceiver,receiver,amount])}async changeVoteType(type){if(!this.#canVote())throw new Error("not a allowed");if("transfer"===this.#voteType&&await this.#balance()>0n)throw new Error("get tokens out first or they be lost forever");this.createVote("change the token amount to receive","set tokenAmountToReceive",(new Date).getTime()+this.votingDuration,"#changeVoteType",[type])}getTokensOut(amount,receiver){if(!this.#canVote())throw new Error("not a allowed");this.createVote("withdraw all tokens",`withdraw all tokens to ${receiver}`,(new Date).getTime()+this.votingDuration,"#getTokensOut",[amount,receiver])}changeTokenAmountToReceive(){if(!this.#canVote())throw new Error("not a allowed");this.createVote("change the token amount to receive","set tokenAmountToReceive",(new Date).getTime()+this.votingDuration,"#changeTokenAmountToReceive",[])}#balance(){return msg.staticCall(this.#tokenToReceive,"balanceOf",[this.#tokenReceiver])}async changeTokenToReceive(){if(!this.#canVote())throw new Error("not a allowed");if(await this.#balance()>0n&&"transfer"===this.#voteType)throw new Error("get tokens out first or they be lost forever");this.createVote("change the token to receive","set tokenToReceive to a new address",(new Date).getTime()+this.votingDuration,"#changeTokenToReceive",[])}}class NameService extends TokenReceiver{#name="LeofcoinNameService";#registry={};get name(){return this.#name}get registry(){return{...this.#registry}}get state(){return{...super.state,registry:this.#registry}}constructor(factoryAddress,tokenToReceive,validatorAddress,tokenAmountToReceive,state){super(tokenToReceive,tokenAmountToReceive,!0,state),state?this.#registry=state.registry:(this.#registry.LeofcoinContractFactory={owner:msg.sender,address:factoryAddress},this.#registry.LeofcoinToken={owner:msg.sender,address:tokenToReceive},this.#registry.LeofcoinValidators={owner:msg.sender,address:validatorAddress})}async purchaseName(name,address){await this._canPay(),await this._payTokenToReceive(),this.#registry[name]={owner:msg.sender,address:address}}lookup(name){return this.#registry[name]}transferOwnership(name,to){if(msg.sender!==this.#registry[name].owner)throw new Error("not allowed");this.#registry[name].owner=to}changeAddress(name,address){if(msg.sender!==this.#registry[name].owner)throw new Error("not allowed");this.#registry[name].address=address}}export{NameService as default};
@@ -1 +1 @@
1
- class ContractCreator{#creator;constructor(state){this.#creator=state?state.contractCreator:msg.sender}get _contractCreator(){return this.#creator}get state(){return{contractCreator:this.#creator}}get _isContractCreator(){return msg.sender===this.#creator}}class Roles extends ContractCreator{#roles={OWNER:[],MINT:[],BURN:[]};constructor(state){if(super(state),state?.roles){if(!(state.roles instanceof Object))throw new TypeError("expected roles to be an object");this.#roles={...state.roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER")}get state(){return{...super.state,roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&this.#roles[role].includes(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}class Token extends Roles{#name;#symbol;#holders=BigNumber.from(0);#balances={};#approvals={};#decimals=18;#totalSupply=BigNumber.from(0);#stakingContract;constructor(name,symbol,decimals=18,state){if(!name)throw new Error("name undefined");if(!symbol)throw new Error("symbol undefined");super(state),state?(this.#balances=(balances=>{const _balances={};for(const address in balances)_balances[address]=BigNumber.from(balances[address]);return _balances})(state.balances),this.#approvals=(approvals=>{const _approvals={};for(const owner in approvals){_approvals[owner]={};for(const operator in approvals[owner])_approvals[owner][operator]=BigNumber.from(approvals[owner][operator])}return _approvals})(state.approvals),this.#holders=BigNumber.from(state.holders),this.#totalSupply=BigNumber.from(state.totalSupply),this.#name=name,this.#symbol=symbol,this.#decimals=decimals):(this.#name=name,this.#symbol=symbol,this.#decimals=decimals)}get state(){return{...super.state,name:this.#name,symbol:this.#symbol,decimals:this.#decimals,holders:this.holders,balances:this.balances,approvals:{...this.#approvals},totalSupply:this.totalSupply}}get totalSupply(){return this.#totalSupply}get name(){return this.#name}get symbol(){return this.#symbol}get holders(){return this.#holders}get balances(){return{...this.#balances}}get approvals(){return this.#approvals}get decimals(){return this.#decimals}mint(to,amount){if(!this.hasRole(msg.sender,"MINT"))throw new Error("not allowed");this.#totalSupply=this.#totalSupply.add(amount),this.#increaseBalance(to,amount)}burn(from,amount){if(!this.hasRole(msg.sender,"BURN")||msg.sender!==from)throw new Error("not allowed");const total=this.#totalSupply.sub(amount);total.gte(0)&&(this.#totalSupply=total,this.#decreaseBalance(from,amount))}#beforeTransfer(from,to,amount){if(!this.#balances[from]||this.#balances[from]<amount)throw new Error("amount exceeds balance")}#updateHolders(address,previousBalance){"0x00"===this.#balances[address].toHexString()?this.#holders.sub(1):"0x00"!==this.#balances[address].toHexString()&&"0x00"===previousBalance.toHexString()&&this.#holders.add(1)}#increaseBalance(address,amount){this.#balances[address]||(this.#balances[address]=BigNumber.from(0));const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].add(amount),this.#updateHolders(address,previousBalance)}#decreaseBalance(address,amount){const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].sub(amount),this.#updateHolders(address,previousBalance)}balance(){return this.#balances[msg.sender]}balanceOf(address){return this.#balances[address]}setApproval(operator,amount){const owner=msg.sender;this.#approvals[owner]||(this.#approvals[owner]={}),this.#approvals[owner][operator]=BigNumber.from(amount)}approved(owner,operator,amount){return this.#approvals[owner][operator]===amount}transfer(from,to,amount){amount=BigNumber.from(amount),this.#beforeTransfer(from,to,amount),this.#decreaseBalance(from,amount),this.#increaseBalance(to,amount)}}class Leofcoin extends Token{constructor(state){super("Leofcoin","LFC",18,state)}}export{Leofcoin as default};
1
+ class ContractCreator{#creator;constructor(state){this.#creator=state?state.contractCreator:msg.sender}get _contractCreator(){return this.#creator}get state(){return{contractCreator:this.#creator}}get _isContractCreator(){return msg.sender===this.#creator}}class Roles extends ContractCreator{#roles={OWNER:[],MINT:[],BURN:[]};constructor(state){if(super(state),state?.roles){if(!(state.roles instanceof Object))throw new TypeError("expected roles to be an object");this.#roles={...state.roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER")}get state(){return{...super.state,roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&this.#roles[role].includes(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}class Token extends Roles{#name;#symbol;#holders=BigInt(0);#balances={};#approvals={};#decimals=18;#totalSupply=BigInt(0);#maxSupply=BigInt(0);#stakingContract;constructor(name,symbol,decimals=18,state){if(!name)throw new Error("name undefined");if(!symbol)throw new Error("symbol undefined");super(state),state?(this.#balances=(balances=>{const _balances={};for(const address in balances)_balances[address]=BigInt(balances[address]);return _balances})(state.balances),this.#approvals=(approvals=>{const _approvals={};for(const owner in approvals){_approvals[owner]={};for(const operator in approvals[owner])_approvals[owner][operator]=BigInt(approvals[owner][operator])}return _approvals})(state.approvals),this.#holders=BigInt(state.holders),this.#totalSupply=BigInt(state.totalSupply),this.#name=name,this.#symbol=symbol,this.#decimals=decimals,this.#maxSupply=BigInt(state.maxSupply)):(this.#name=name,this.#symbol=symbol,this.#decimals=decimals)}get state(){return{...super.state,name:this.#name,symbol:this.#symbol,decimals:this.#decimals,holders:this.holders,balances:this.balances,approvals:{...this.#approvals},totalSupply:this.totalSupply,maxSupply:this.#maxSupply}}get maxSupply(){return this.#maxSupply}get totalSupply(){return this.#totalSupply}get name(){return this.#name}get symbol(){return this.#symbol}get holders(){return this.#holders}get balances(){return{...this.#balances}}get approvals(){return this.#approvals}get decimals(){return this.#decimals}mint(to,amount){if(!this.hasRole(msg.sender,"MINT"))throw new Error("mint role required");const supply=this.#totalSupply+amount;if(0n===this.#maxSupply)this.#totalSupply=supply,this.#increaseBalance(to,amount);else{if(!(supply<=this.#maxSupply))throw new Error("amount exceeds max supply");this.#totalSupply=supply,this.#increaseBalance(to,amount)}}burn(from,amount){if(!this.hasRole(msg.sender,"BURN")&&msg.sender!==from)throw new Error("not the owner or burn role required");if(this.#balances[from]<amount)throw new Error("amount exceeds balance");const total=this.#totalSupply-amount;if(!(total>=0))throw new Error("amount exceeds total supply");this.#totalSupply=total,this.#decreaseBalance(from,amount)}#beforeTransfer(from,to,amount){if(!this.#balances[from]||this.#balances[from]<amount)throw new Error("amount exceeds balance")}#updateHolders(address,previousBalance){0n===this.#balances[address]?this.#holders-=1n:0n!==this.#balances[address]&&0n===previousBalance&&(this.#holders+=1n)}#increaseBalance(address,amount){this.#balances[address]||(this.#balances[address]=BigInt(0));const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address]+=amount,this.#updateHolders(address,previousBalance)}#decreaseBalance(address,amount){const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address]-=amount,this.#updateHolders(address,previousBalance)}balance(){return this.#balances[msg.sender]}balanceOf(address){return this.#balances[address]}setApproval(operator,amount){const owner=msg.sender;this.#approvals[owner]||(this.#approvals[owner]={}),this.#approvals[owner][operator]=BigInt(amount)}approved(owner,operator,amount){return this.#approvals[owner][operator]===amount}transfer(from,to,amount){amount=BigInt(amount),this.#beforeTransfer(from,to,amount),this.#decreaseBalance(from,amount),this.#increaseBalance(to,amount)}}class Leofcoin extends Token{constructor(state){super("Leofcoin","LFC",18,state)}}export{Leofcoin as default};
@@ -1 +1 @@
1
- class ContractCreator{#creator;constructor(state){this.#creator=state?state.contractCreator:msg.sender}get _contractCreator(){return this.#creator}get state(){return{contractCreator:this.#creator}}get _isContractCreator(){return msg.sender===this.#creator}}class Roles extends ContractCreator{#roles={OWNER:[],MINT:[],BURN:[]};constructor(state){if(super(state),state?.roles){if(!(state.roles instanceof Object))throw new TypeError("expected roles to be an object");this.#roles={...state.roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER")}get state(){return{...super.state,roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&this.#roles[role].includes(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}class Token extends Roles{#name;#symbol;#holders=BigNumber.from(0);#balances={};#approvals={};#decimals=18;#totalSupply=BigNumber.from(0);#stakingContract;constructor(name,symbol,decimals=18,state){if(!name)throw new Error("name undefined");if(!symbol)throw new Error("symbol undefined");super(state),state?(this.#balances=(balances=>{const _balances={};for(const address in balances)_balances[address]=BigNumber.from(balances[address]);return _balances})(state.balances),this.#approvals=(approvals=>{const _approvals={};for(const owner in approvals){_approvals[owner]={};for(const operator in approvals[owner])_approvals[owner][operator]=BigNumber.from(approvals[owner][operator])}return _approvals})(state.approvals),this.#holders=BigNumber.from(state.holders),this.#totalSupply=BigNumber.from(state.totalSupply),this.#name=name,this.#symbol=symbol,this.#decimals=decimals):(this.#name=name,this.#symbol=symbol,this.#decimals=decimals)}get state(){return{...super.state,name:this.#name,symbol:this.#symbol,decimals:this.#decimals,holders:this.holders,balances:this.balances,approvals:{...this.#approvals},totalSupply:this.totalSupply}}get totalSupply(){return this.#totalSupply}get name(){return this.#name}get symbol(){return this.#symbol}get holders(){return this.#holders}get balances(){return{...this.#balances}}get approvals(){return this.#approvals}get decimals(){return this.#decimals}mint(to,amount){if(!this.hasRole(msg.sender,"MINT"))throw new Error("not allowed");this.#totalSupply=this.#totalSupply.add(amount),this.#increaseBalance(to,amount)}burn(from,amount){if(!this.hasRole(msg.sender,"BURN")||msg.sender!==from)throw new Error("not allowed");const total=this.#totalSupply.sub(amount);total.gte(0)&&(this.#totalSupply=total,this.#decreaseBalance(from,amount))}#beforeTransfer(from,to,amount){if(!this.#balances[from]||this.#balances[from]<amount)throw new Error("amount exceeds balance")}#updateHolders(address,previousBalance){"0x00"===this.#balances[address].toHexString()?this.#holders.sub(1):"0x00"!==this.#balances[address].toHexString()&&"0x00"===previousBalance.toHexString()&&this.#holders.add(1)}#increaseBalance(address,amount){this.#balances[address]||(this.#balances[address]=BigNumber.from(0));const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].add(amount),this.#updateHolders(address,previousBalance)}#decreaseBalance(address,amount){const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].sub(amount),this.#updateHolders(address,previousBalance)}balance(){return this.#balances[msg.sender]}balanceOf(address){return this.#balances[address]}setApproval(operator,amount){const owner=msg.sender;this.#approvals[owner]||(this.#approvals[owner]={}),this.#approvals[owner][operator]=BigNumber.from(amount)}approved(owner,operator,amount){return this.#approvals[owner][operator]===amount}transfer(from,to,amount){amount=BigNumber.from(amount),this.#beforeTransfer(from,to,amount),this.#decreaseBalance(from,amount),this.#increaseBalance(to,amount)}}class Power extends Token{constructor(state){super("Power","PWR",18,state)}}export{Power as default};
1
+ class ContractCreator{#creator;constructor(state){this.#creator=state?state.contractCreator:msg.sender}get _contractCreator(){return this.#creator}get state(){return{contractCreator:this.#creator}}get _isContractCreator(){return msg.sender===this.#creator}}class Roles extends ContractCreator{#roles={OWNER:[],MINT:[],BURN:[]};constructor(state){if(super(state),state?.roles){if(!(state.roles instanceof Object))throw new TypeError("expected roles to be an object");this.#roles={...state.roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER")}get state(){return{...super.state,roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&this.#roles[role].includes(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}class Token extends Roles{#name;#symbol;#holders=BigInt(0);#balances={};#approvals={};#decimals=18;#totalSupply=BigInt(0);#maxSupply=BigInt(0);#stakingContract;constructor(name,symbol,decimals=18,state){if(!name)throw new Error("name undefined");if(!symbol)throw new Error("symbol undefined");super(state),state?(this.#balances=(balances=>{const _balances={};for(const address in balances)_balances[address]=BigInt(balances[address]);return _balances})(state.balances),this.#approvals=(approvals=>{const _approvals={};for(const owner in approvals){_approvals[owner]={};for(const operator in approvals[owner])_approvals[owner][operator]=BigInt(approvals[owner][operator])}return _approvals})(state.approvals),this.#holders=BigInt(state.holders),this.#totalSupply=BigInt(state.totalSupply),this.#name=name,this.#symbol=symbol,this.#decimals=decimals,this.#maxSupply=BigInt(state.maxSupply)):(this.#name=name,this.#symbol=symbol,this.#decimals=decimals)}get state(){return{...super.state,name:this.#name,symbol:this.#symbol,decimals:this.#decimals,holders:this.holders,balances:this.balances,approvals:{...this.#approvals},totalSupply:this.totalSupply,maxSupply:this.#maxSupply}}get maxSupply(){return this.#maxSupply}get totalSupply(){return this.#totalSupply}get name(){return this.#name}get symbol(){return this.#symbol}get holders(){return this.#holders}get balances(){return{...this.#balances}}get approvals(){return this.#approvals}get decimals(){return this.#decimals}mint(to,amount){if(!this.hasRole(msg.sender,"MINT"))throw new Error("mint role required");const supply=this.#totalSupply+amount;if(0n===this.#maxSupply)this.#totalSupply=supply,this.#increaseBalance(to,amount);else{if(!(supply<=this.#maxSupply))throw new Error("amount exceeds max supply");this.#totalSupply=supply,this.#increaseBalance(to,amount)}}burn(from,amount){if(!this.hasRole(msg.sender,"BURN")&&msg.sender!==from)throw new Error("not the owner or burn role required");if(this.#balances[from]<amount)throw new Error("amount exceeds balance");const total=this.#totalSupply-amount;if(!(total>=0))throw new Error("amount exceeds total supply");this.#totalSupply=total,this.#decreaseBalance(from,amount)}#beforeTransfer(from,to,amount){if(!this.#balances[from]||this.#balances[from]<amount)throw new Error("amount exceeds balance")}#updateHolders(address,previousBalance){0n===this.#balances[address]?this.#holders-=1n:0n!==this.#balances[address]&&0n===previousBalance&&(this.#holders+=1n)}#increaseBalance(address,amount){this.#balances[address]||(this.#balances[address]=BigInt(0));const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address]+=amount,this.#updateHolders(address,previousBalance)}#decreaseBalance(address,amount){const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address]-=amount,this.#updateHolders(address,previousBalance)}balance(){return this.#balances[msg.sender]}balanceOf(address){return this.#balances[address]}setApproval(operator,amount){const owner=msg.sender;this.#approvals[owner]||(this.#approvals[owner]={}),this.#approvals[owner][operator]=BigInt(amount)}approved(owner,operator,amount){return this.#approvals[owner][operator]===amount}transfer(from,to,amount){amount=BigInt(amount),this.#beforeTransfer(from,to,amount),this.#decreaseBalance(from,amount),this.#increaseBalance(to,amount)}}class Power extends Token{constructor(state){super("Power","PWR",18,state)}}export{Power as default};
@@ -1,17 +1,18 @@
1
+ /// <reference types="@leofcoin/types/global" />
1
2
  import { TokenReceiver } from '@leofcoin/standards';
2
3
  import type { PublicVotingState } from '@leofcoin/standards/public-voting';
3
4
  import { TokenReceiverState } from '@leofcoin/standards/token-receiver';
4
5
  export interface FactoryState extends TokenReceiverState {
5
6
  contracts: any[];
6
- totalContracts: typeof BigNumber;
7
+ totalContracts: bigint;
7
8
  }
8
9
  export default class Factory extends TokenReceiver {
9
10
  #private;
10
- constructor(tokenToReceive: address, tokenAmountToReceive: typeof BigNumber, state: FactoryState);
11
+ constructor(tokenToReceive: address, tokenAmountToReceive: bigint, state: FactoryState);
11
12
  get state(): PublicVotingState;
12
13
  get name(): string;
13
14
  get contracts(): string[];
14
- get totalContracts(): import("@ethersproject/bignumber").BigNumber;
15
+ get totalContracts(): bigint;
15
16
  isRegistered(address: any): boolean;
16
17
  /**
17
18
  *
@@ -1,3 +1,4 @@
1
+ /// <reference types="@leofcoin/types/global" />
1
2
  import { TokenReceiver } from '@leofcoin/standards';
2
3
  import { TokenReceiverState } from '@leofcoin/standards/token-receiver';
3
4
  type registry = {
@@ -14,7 +15,7 @@ export default class NameService extends TokenReceiver {
14
15
  get name(): string;
15
16
  get registry(): {};
16
17
  get state(): NameServiceState;
17
- constructor(factoryAddress: address, tokenToReceive: address, validatorAddress: address, tokenAmountToReceive: typeof BigNumber, state: NameServiceState);
18
+ constructor(factoryAddress: address, tokenToReceive: address, validatorAddress: address, tokenAmountToReceive: bigint, state: NameServiceState);
18
19
  purchaseName(name: string | number, address: any): Promise<void>;
19
20
  lookup(name: string | number): any;
20
21
  transferOwnership(name: string | number, to: any): void;
@@ -1,21 +1,36 @@
1
- import Roles from '@leofcoin/standards/roles.js';
1
+ /// <reference types="@leofcoin/types/global" />
2
+ import Roles, { RolesState } from '@leofcoin/standards/roles.js';
3
+ export declare interface ValidatorsState extends RolesState {
4
+ balances: {
5
+ [address: string]: bigint;
6
+ };
7
+ minimumBalance: bigint;
8
+ currency: address;
9
+ validators: address[];
10
+ currentValidator: address;
11
+ }
2
12
  export default class Validators extends Roles {
3
13
  #private;
4
14
  get state(): {
5
- minimumBalance: import("@ethersproject/bignumber").BigNumber;
15
+ balances: {
16
+ [address: string]: bigint;
17
+ };
18
+ minimumBalance: bigint;
6
19
  currency: string;
7
20
  validators: string[];
21
+ currentValidator: string;
8
22
  roles: {
9
23
  [index: string]: string[];
10
24
  };
11
25
  contractCreator: string;
12
26
  };
13
- constructor(tokenAddress: address, state: any);
27
+ constructor(tokenAddress: address, state: ValidatorsState);
28
+ get currentValidator(): string;
14
29
  get name(): string;
15
30
  get currency(): string;
16
31
  get validators(): string[];
17
32
  get totalValidators(): number;
18
- get minimumBalance(): import("@ethersproject/bignumber").BigNumber;
33
+ get minimumBalance(): bigint;
19
34
  changeCurrency(currency: any): void;
20
35
  has(validator: any): boolean;
21
36
  addValidator(validator: address): Promise<void>;
@@ -1,23 +1,38 @@
1
- import Roles from '@leofcoin/standards/roles.js';
1
+ import Roles, { RolesState } from '@leofcoin/standards/roles.js';
2
+ export declare interface ValidatorsState extends RolesState {
3
+ balances: {
4
+ [address: string]: bigint;
5
+ };
6
+ minimumBalance: bigint;
7
+ currency: address;
8
+ validators: address[];
9
+ currentValidator: address;
10
+ }
2
11
  export default class Validators extends Roles {
3
12
  #private;
4
13
  get state(): {
5
- minimumBalance: import("@ethersproject/bignumber").BigNumber;
14
+ balances: {
15
+ [address: string]: bigint;
16
+ };
17
+ minimumBalance: bigint;
6
18
  currency: string;
7
19
  validators: string[];
20
+ currentValidator: string;
8
21
  roles: {
9
- [index: string]: string[];
22
+ [index: string]: address[];
10
23
  };
11
- contractCreator: string;
24
+ contractCreator: address;
12
25
  };
13
- constructor(tokenAddress: address, state: any);
26
+ constructor(tokenAddress: address, state: ValidatorsState);
27
+ get currentValidator(): string;
14
28
  get name(): string;
15
29
  get currency(): string;
16
30
  get validators(): string[];
17
31
  get totalValidators(): number;
18
- get minimumBalance(): import("@ethersproject/bignumber").BigNumber;
32
+ get minimumBalance(): bigint;
19
33
  changeCurrency(currency: any): void;
20
34
  has(validator: any): boolean;
21
35
  addValidator(validator: address): Promise<void>;
22
- removeValidator(validator: any): void;
36
+ removeValidator(validator: any): Promise<void>;
37
+ shuffleValidator(): void;
23
38
  }
@@ -1 +1 @@
1
- class ContractCreator{#creator;constructor(state){this.#creator=state?state.contractCreator:msg.sender}get _contractCreator(){return this.#creator}get state(){return{contractCreator:this.#creator}}get _isContractCreator(){return msg.sender===this.#creator}}class Roles extends ContractCreator{#roles={OWNER:[],MINT:[],BURN:[]};constructor(state){if(super(state),state?.roles){if(!(state.roles instanceof Object))throw new TypeError("expected roles to be an object");this.#roles={...state.roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER")}get state(){return{...super.state,roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&this.#roles[role].includes(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}const between=(min,max,length=1)=>{let arr=[];for(let i=0;i<length;++i)arr=[...arr,Math.floor(Math.random()*(max+1-min)+min)];return arr},lottery=(numbers=7,max=100,min=0,length=100)=>{let arr=[],ran=between(min,max,length);ran=(arr=>arr.filter(((el,pos,arr)=>arr.indexOf(el)==pos)))(ran);for(let i=0;i<numbers;++i){const _ran=between(min,ran.length-1,ran.length)[0];arr=[...arr,ran[_ran]]}return arr};class Validators extends Roles{#name="LeofcoinValidators";#validators=[];#currentValidator;#currency;#minimumBalance;#balances;get state(){return{...super.state,minimumBalance:this.#minimumBalance,currency:this.#currency,validators:this.#validators}}constructor(tokenAddress,state){super(state?.roles),state?(this.#minimumBalance=BigNumber.from(state.minimumBalance),this.#currency=state.currency,this.#validators=state.validators):(this.#minimumBalance=BigNumber.from(5e4),this.#currency=tokenAddress,this.#validators.push(msg.sender))}get name(){return this.#name}get currency(){return this.#currency}get validators(){return[...this.#validators]}get totalValidators(){return this.#validators.length}get minimumBalance(){return this.#minimumBalance}changeCurrency(currency){if(!this.hasRole(msg.sender,"OWNER"))throw new Error("not an owner");this.#currency=currency}has(validator){return this.#validators.includes(validator)}#isAllowed(address){if(msg.sender!==address&&!this.hasRole(msg.sender,"OWNER"))throw new Error("sender is not the validator or owner");return!0}async addValidator(validator){if(this.#isAllowed(validator),this.has(validator))throw new Error("already a validator");const balance=await msg.staticCall(this.currency,"balanceOf",[validator]);if(this.minimumBalance.gt(balance))throw new Error(`balance to low! got: ${balance} need: ${this.#minimumBalance}`);await msg.call(this.currency,"transfer",[validator,msg.contract,this.#minimumBalance]),this.#balances[validator]=this.#minimumBalance,this.#validators.push(validator)}async removeValidator(validator){if(this.#isAllowed(validator),!this.has(validator))throw new Error("validator not found");await msg.call(this.currency,"transfer",[msg.contract,validator,this.#minimumBalance]),delete this.#balances[validator],this.#validators.splice(this.#validators.indexOf(validator))}shuffleValidator(){const _peers=globalThis.peernet.peers,peers=_peers.filter((peer=>this.#validators[peer[0]])).map((peer=>(peer[1].totalBytes=peer[1].bw.up+peer[1].bw.down,peer))).sort(((a,b)=>b[1].totalBytes-a[1].totalBytes)).splice(0,_peers.length>128?128:_peers.length),luckyNumber=lottery(1,peers.length);let nextValidator=this.#validators[peers[luckyNumber[0]][0]];if(this.#currentValidator===nextValidator&&1!==peers.length){const luckyNumber=lottery(1,peers.length);nextValidator=this.#validators[peers[luckyNumber[0]][0]]}this.#currentValidator=nextValidator}}export{Validators as default};
1
+ const between=(min,max,length=1)=>{let arr=[];for(let i=0;i<length;++i)arr=[...arr,Math.floor(Math.random()*(max+1-min)+min)];return arr},lottery=(numbers=7,max=100,min=0,length=100)=>{let arr=[],ran=between(min,max,length);ran=(arr=>arr.filter(((el,pos,arr)=>arr.indexOf(el)==pos)))(ran);for(let i=0;i<numbers;++i){const _ran=between(min,ran.length-1,ran.length)[0];arr=[...arr,ran[_ran]]}return arr};class ContractCreator{#creator;constructor(state){this.#creator=state?state.contractCreator:msg.sender}get _contractCreator(){return this.#creator}get state(){return{contractCreator:this.#creator}}get _isContractCreator(){return msg.sender===this.#creator}}class Roles extends ContractCreator{#roles={OWNER:[],MINT:[],BURN:[]};constructor(state){if(super(state),state?.roles){if(!(state.roles instanceof Object))throw new TypeError("expected roles to be an object");this.#roles={...state.roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER")}get state(){return{...super.state,roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&this.#roles[role].includes(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}class Validators extends Roles{#name="LeofcoinValidators";#validators=[];#currentValidator;#currency;#minimumBalance=BigInt(5e4);#balances={};get state(){return{...super.state,balances:this.#balances,minimumBalance:this.#minimumBalance,currency:this.#currency,validators:this.#validators,currentValidator:this.#currentValidator}}constructor(tokenAddress,state){super(state?.roles),state?(this.#minimumBalance=BigInt(state.minimumBalance),this.#currency=state.currency,this.#validators=state.validators,this.#balances=state.balances,this.#currentValidator=state.currentValidator):(this.#currency=tokenAddress,this.#validators.push(msg.sender),this.#currentValidator=msg.sender)}get currentValidator(){return this.#currentValidator}get name(){return this.#name}get currency(){return this.#currency}get validators(){return this.#validators}get totalValidators(){return this.#validators.length}get minimumBalance(){return this.#minimumBalance}changeCurrency(currency){if(!this.hasRole(msg.sender,"OWNER"))throw new Error("not an owner");this.#currency=currency}has(validator){return this.#validators.includes(validator)}#isAllowed(address){if(msg.sender!==address&&!this.hasRole(msg.sender,"OWNER"))throw new Error("sender is not the validator or owner");return!0}async addValidator(validator){if(this.#isAllowed(validator),this.has(validator))throw new Error("validator already exists");const balance=await msg.staticCall(this.currency,"balanceOf",[validator]);if(this.minimumBalance>balance)throw new Error(`balance to low! got: ${balance} need: ${this.#minimumBalance}`);await msg.call(this.currency,"transfer",[validator,msg.contract,this.#minimumBalance]),this.#balances[validator]=this.#minimumBalance,this.#validators.push(validator)}async removeValidator(validator){if(this.#isAllowed(validator),!this.has(validator))throw new Error("validator not found");await msg.call(this.currency,"transfer",[msg.contract,validator,this.#minimumBalance]),delete this.#balances[validator],this.#validators.splice(this.#validators.indexOf(validator),1)}shuffleValidator(){const _peers=state.peers,peers=_peers.filter((peer=>this.#validators.includes(peer[0]))).map((peer=>(peer[1].totalBytes=peer[1].bw.up+peer[1].bw.down,peer))).sort(((a,b)=>b[1].totalBytes-a[1].totalBytes)).splice(0,_peers.length>128?128:_peers.length);let nextValidator=peers[lottery(1,peers.length-1)[0]][0];if(this.#currentValidator===nextValidator&&1!==peers.length){nextValidator=peers[lottery(1,peers.length-1)[0]][0]}this.#currentValidator=nextValidator}}export{Validators as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/contracts",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "exports": {
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "scripts": {
14
14
  "build": "rollup -c",
15
- "test": "echo \"Error: no test specified\" && exit 1"
15
+ "test": "mocha test/**/*.js"
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",
@@ -26,16 +26,18 @@
26
26
  },
27
27
  "homepage": "https://github.com/leofcoin/contracts#readme",
28
28
  "dependencies": {
29
- "@changesets/cli": "^2.27.1",
30
- "@leofcoin/global-types": "^1.0.0",
31
- "@leofcoin/standards": "^0.2.2",
32
- "lucky-numbers": "^1.2.0"
29
+ "@leofcoin/standards": "^0.2.11",
30
+ "lucky-numbers": "^1.2.1"
33
31
  },
34
32
  "devDependencies": {
35
- "@rollup/plugin-node-resolve": "^15.0.1",
36
- "@rollup/plugin-terser": "^0.4.0",
37
- "@rollup/plugin-typescript": "^11.0.0",
38
- "rollup": "^3.17.2",
39
- "tslib": "^2.5.0"
33
+ "@leofcoin/types": "^1.0.17",
34
+ "@rollup/plugin-node-resolve": "^15.2.3",
35
+ "@rollup/plugin-terser": "^0.4.4",
36
+ "@rollup/plugin-typescript": "^11.1.6",
37
+ "chai": "^5.1.1",
38
+ "chai-as-promised": "^8.0.0",
39
+ "mocha": "^10.7.3",
40
+ "rollup": "^4.22.2",
41
+ "tslib": "^2.7.0"
40
42
  }
41
43
  }
package/src/factory.ts CHANGED
@@ -4,7 +4,7 @@ import { TokenReceiverState } from '@leofcoin/standards/token-receiver'
4
4
 
5
5
  export interface FactoryState extends TokenReceiverState {
6
6
  contracts: any[]
7
- totalContracts: typeof BigNumber
7
+ totalContracts: bigint
8
8
  }
9
9
 
10
10
  export default class Factory extends TokenReceiver {
@@ -15,13 +15,13 @@ export default class Factory extends TokenReceiver {
15
15
  /**
16
16
  * uint
17
17
  */
18
- #totalContracts: typeof BigNumber = BigNumber['from'](0)
18
+ #totalContracts: bigint = BigInt(0)
19
19
  /**
20
20
  * Array => string
21
21
  */
22
22
  #contracts: address[] = []
23
23
 
24
- constructor(tokenToReceive: address, tokenAmountToReceive: typeof BigNumber, state: FactoryState) {
24
+ constructor(tokenToReceive: address, tokenAmountToReceive: bigint, state: FactoryState) {
25
25
  super(tokenToReceive, tokenAmountToReceive, true, state as TokenReceiverState)
26
26
  if (state) {
27
27
  this.#contracts = state.contracts
@@ -67,7 +67,7 @@ export default class Factory extends TokenReceiver {
67
67
  if (!(await this.#isCreator(address))) throw new Error(`You don't own that contract`)
68
68
  if (this.#contracts.includes(address)) throw new Error('already registered')
69
69
  await this._payTokenToReceive()
70
- this.#totalContracts.add(1)
70
+ this.#totalContracts += 1n
71
71
  this.#contracts.push(address)
72
72
  }
73
73
  }
@@ -42,7 +42,7 @@ export default class NameService extends TokenReceiver {
42
42
  factoryAddress: address,
43
43
  tokenToReceive: address,
44
44
  validatorAddress: address,
45
- tokenAmountToReceive: typeof BigNumber,
45
+ tokenAmountToReceive: bigint,
46
46
  state: NameServiceState
47
47
  ) {
48
48
  super(tokenToReceive, tokenAmountToReceive, true, state as TokenReceiverState)
@@ -1,7 +1,7 @@
1
- import Token, { TokenState } from '@leofcoin/standards/token.js';
1
+ import Token, { TokenState } from '@leofcoin/standards/token.js'
2
2
 
3
3
  export default class Leofcoin extends Token {
4
4
  constructor(state: TokenState) {
5
- super('Leofcoin', 'LFC', 18, state);
5
+ super('Leofcoin', 'LFC', 18, state)
6
6
  }
7
7
  }
@@ -1,7 +1,7 @@
1
- import Token, { TokenState } from '@leofcoin/standards/token.js';
1
+ import Token, { TokenState } from '@leofcoin/standards/token.js'
2
2
 
3
3
  export default class Power extends Token {
4
4
  constructor(state: TokenState) {
5
- super('Power', 'PWR', 18, state);
5
+ super('Power', 'PWR', 18, state)
6
6
  }
7
7
  }
package/src/validators.ts CHANGED
@@ -1,5 +1,13 @@
1
- import Roles from '@leofcoin/standards/roles.js'
2
1
  import { lottery } from 'lucky-numbers'
2
+ import Roles, { RolesState } from '@leofcoin/standards/roles.js'
3
+
4
+ export declare interface ValidatorsState extends RolesState {
5
+ balances: { [address: string]: bigint }
6
+ minimumBalance: bigint
7
+ currency: address
8
+ validators: address[]
9
+ currentValidator: address
10
+ }
3
11
 
4
12
  export default class Validators extends Roles {
5
13
  /**
@@ -11,36 +19,44 @@ export default class Validators extends Roles {
11
19
  */
12
20
  #validators: address[] = []
13
21
 
14
- #currentValidator
22
+ #currentValidator: address
15
23
 
16
24
  #currency: address
17
25
 
18
- #minimumBalance: typeof BigNumber
26
+ #minimumBalance: bigint = BigInt(50_000)
19
27
 
20
- #balances: { [address: address]: typeof BigNumber }
28
+ #balances: { [address: address]: bigint } = {}
21
29
 
22
30
  get state() {
23
31
  return {
24
32
  ...super.state,
33
+ balances: this.#balances,
25
34
  minimumBalance: this.#minimumBalance,
26
35
  currency: this.#currency,
27
- validators: this.#validators
36
+ validators: this.#validators,
37
+ currentValidator: this.#currentValidator
28
38
  }
29
39
  }
30
40
 
31
- constructor(tokenAddress: address, state) {
41
+ constructor(tokenAddress: address, state: ValidatorsState) {
32
42
  super(state?.roles)
33
43
  if (state) {
34
- this.#minimumBalance = BigNumber['from'](state.minimumBalance)
44
+ this.#minimumBalance = BigInt(state.minimumBalance)
35
45
  this.#currency = state.currency
36
46
  this.#validators = state.validators
47
+ this.#balances = state.balances
48
+ this.#currentValidator = state.currentValidator
37
49
  } else {
38
- this.#minimumBalance = BigNumber['from'](50_000)
39
50
  this.#currency = tokenAddress
40
51
  this.#validators.push(msg.sender)
52
+ this.#currentValidator = msg.sender
41
53
  }
42
54
  }
43
55
 
56
+ get currentValidator() {
57
+ return this.#currentValidator
58
+ }
59
+
44
60
  get name() {
45
61
  return this.#name
46
62
  }
@@ -50,7 +66,7 @@ export default class Validators extends Roles {
50
66
  }
51
67
 
52
68
  get validators() {
53
- return [...this.#validators]
69
+ return this.#validators
54
70
  }
55
71
 
56
72
  get totalValidators() {
@@ -78,14 +94,15 @@ export default class Validators extends Roles {
78
94
 
79
95
  async addValidator(validator: address) {
80
96
  this.#isAllowed(validator)
81
- if (this.has(validator)) throw new Error('already a validator')
97
+ if (this.has(validator)) throw new Error('validator already exists')
82
98
 
83
99
  const balance = await msg.staticCall(this.currency, 'balanceOf', [validator])
84
100
 
85
- if (this.minimumBalance.gt(balance))
101
+ if (this.minimumBalance > balance)
86
102
  throw new Error(`balance to low! got: ${balance} need: ${this.#minimumBalance}`)
87
103
 
88
104
  await msg.call(this.currency, 'transfer', [validator, msg.contract, this.#minimumBalance])
105
+
89
106
  this.#balances[validator] = this.#minimumBalance
90
107
  this.#validators.push(validator)
91
108
  }
@@ -95,7 +112,7 @@ export default class Validators extends Roles {
95
112
  if (!this.has(validator)) throw new Error('validator not found')
96
113
  await msg.call(this.currency, 'transfer', [msg.contract, validator, this.#minimumBalance])
97
114
  delete this.#balances[validator]
98
- this.#validators.splice(this.#validators.indexOf(validator))
115
+ this.#validators.splice(this.#validators.indexOf(validator), 1)
99
116
  }
100
117
 
101
118
  shuffleValidator() {
@@ -103,10 +120,10 @@ export default class Validators extends Roles {
103
120
  // select amount of peers to vote & pass when 2/3 select the same peer
104
121
  // this.vote
105
122
  // todo only ids should be accessable
106
- const _peers = globalThis.peernet.peers
123
+ const _peers = state.peers
107
124
  const peers = _peers
108
125
  // only validators make a chance
109
- .filter((peer) => this.#validators[peer[0]])
126
+ .filter((peer) => this.#validators.includes(peer[0]))
110
127
  // add up the bytes
111
128
  .map((peer) => {
112
129
  peer[1].totalBytes = peer[1].bw.up + peer[1].bw.down
@@ -116,13 +133,14 @@ export default class Validators extends Roles {
116
133
  // only return 128 best participating max
117
134
  .splice(0, _peers.length > 128 ? 128 : _peers.length)
118
135
 
119
- const luckyNumber = lottery(1, peers.length)
120
- let nextValidator = this.#validators[peers[luckyNumber[0]][0]]
136
+ const luckyNumber = lottery(1, peers.length - 1)
137
+
138
+ let nextValidator = peers[luckyNumber[0]][0]
121
139
  // redraw when the validator is the same
122
140
  // but keep the net alive when only one validator is found
123
141
  if (this.#currentValidator === nextValidator && peers.length !== 1) {
124
- const luckyNumber = lottery(1, peers.length)
125
- nextValidator = this.#validators[peers[luckyNumber[0]][0]]
142
+ const luckyNumber = lottery(1, peers.length - 1)
143
+ nextValidator = peers[luckyNumber[0]][0]
126
144
  }
127
145
  this.#currentValidator = nextValidator
128
146
  }
@@ -0,0 +1,66 @@
1
+ import Factory from './../exports/factory.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('Factory', () => {
5
+ let factory
6
+
7
+ beforeEach(() => {
8
+ global.msg = {
9
+ sender: '0xOwnerAddress',
10
+ contract: '0xContractAddress',
11
+ staticCall: async (currency, method, args) => {
12
+ console.log(currency, method, args)
13
+ if (method === 'balanceOf') {
14
+ return BigInt(100000)
15
+ } else if (method === '_isContractCreator') {
16
+ return true
17
+ }
18
+ },
19
+ call: async (currency, method, args) => {
20
+ console.log(currency, method, args)
21
+
22
+ if (method === 'balanceOf') {
23
+ return BigInt(100000)
24
+ } else if (method === '_isContractCreator') {
25
+ return true
26
+ }
27
+ }
28
+ }
29
+ factory = new Factory('0xTokenAddress', BigInt(1000))
30
+ })
31
+
32
+ it('should throw an error if balance is too low', async () => {
33
+ factory._canPay = () => false
34
+ try {
35
+ await factory.registerContract('0xContractAddress')
36
+ } catch (error) {
37
+ expect(error.message).to.equal("can't register, balance to low")
38
+ }
39
+ })
40
+
41
+ it('should throw an error if address is not a contract creator', async () => {
42
+ factory._canPay = () => true
43
+ factory.isCreator = async () => false
44
+ try {
45
+ await factory.registerContract('0xContractAddress')
46
+ } catch (error) {
47
+ expect(error.message).to.equal("You don't own that contract")
48
+ }
49
+ })
50
+
51
+ it('should throw an error if contract is already registered', async () => {
52
+ await factory.registerContract('0xContractAddress')
53
+ try {
54
+ await factory.registerContract('0xContractAddress')
55
+ } catch (error) {
56
+ expect(error.message).to.equal('already registered')
57
+ }
58
+ })
59
+
60
+ it('should successfully register a contract', async () => {
61
+ await factory.registerContract('0xContractAddress')
62
+
63
+ expect(factory.totalContracts).to.equal(BigInt(1))
64
+ expect(factory.contracts).to.include('0xContractAddress')
65
+ })
66
+ })
@@ -0,0 +1,96 @@
1
+ import { expect, use } from 'chai'
2
+ import chaiAsPromised from 'chai-as-promised'
3
+ import Leofcoin from './../exports/native-token.js'
4
+ import Token from '@leofcoin/standards/token.js'
5
+
6
+ use(chaiAsPromised)
7
+
8
+ describe('Leofcoin', () => {
9
+ let state
10
+ let token
11
+ const receiverAddress = '0xReceiverAddress'
12
+ const otherReceiverAddress = '0xOtherReceiverAddress'
13
+ const ownerAddress = '0xOwnerAddress'
14
+
15
+ beforeEach(() => {
16
+ global.msg = {
17
+ sender: ownerAddress,
18
+ contract: '0xContractAddress',
19
+ staticCall: async (currency, method, args) => {
20
+ // Mock implementation of msg.staticCall
21
+ },
22
+ call: async (currency, method, args) => {
23
+ // Mock implementation of msg.call
24
+ }
25
+ }
26
+
27
+ token = new Leofcoin()
28
+ })
29
+
30
+ it('should create an instance of Leofcoin', () => {
31
+ expect(token).to.be.instanceOf(Leofcoin)
32
+ })
33
+
34
+ it('should have correct properties', () => {
35
+ expect(token.name).to.equal('Leofcoin')
36
+ expect(token.symbol).to.equal('LFC')
37
+ expect(token.decimals).to.equal(18)
38
+ })
39
+
40
+ it('should grant MINT role to owner', async () => {
41
+ await token.grantRole(ownerAddress, 'MINT')
42
+ expect(await token.hasRole(ownerAddress, 'MINT')).to.equal(true)
43
+ })
44
+
45
+ it('should be able to mint', async () => {
46
+ await token.grantRole(ownerAddress, 'MINT')
47
+ await token.mint(ownerAddress, 100000n)
48
+ expect(token.balanceOf(ownerAddress)).to.equal(100000n)
49
+ })
50
+
51
+ it('should be able to transfer', async () => {
52
+ await token.grantRole(ownerAddress, 'MINT')
53
+ await token.mint(receiverAddress, 100000n)
54
+ msg.sender = receiverAddress
55
+ await token.transfer(receiverAddress, otherReceiverAddress, 10000n)
56
+ expect(token.balanceOf(receiverAddress)).to.equal(90000n)
57
+ expect(token.balanceOf(otherReceiverAddress)).to.equal(10000n)
58
+ })
59
+
60
+ it('should be able to burn', async () => {
61
+ await token.grantRole(ownerAddress, 'BURN')
62
+ await token.grantRole(ownerAddress, 'MINT')
63
+ await token.mint(ownerAddress, 100000n)
64
+ await token.burn(ownerAddress, 10000n)
65
+ expect(token.balanceOf(ownerAddress)).to.equal(90000n)
66
+ })
67
+
68
+ it('should not be able to burn more than balance', async () => {
69
+ await token.grantRole(ownerAddress, 'MINT')
70
+ await token.mint(ownerAddress, 100000n)
71
+
72
+ try {
73
+ await token.burn(ownerAddress, 100001n)
74
+ } catch (error) {
75
+ expect(error.message).to.equal('amount exceeds balance')
76
+ }
77
+ })
78
+
79
+ it('should not be able to mint if not MINT role', async () => {
80
+ try {
81
+ await token.mint(ownerAddress, 100000n)
82
+ } catch (error) {
83
+ expect(error.message).to.equal('mint role required')
84
+ }
85
+ })
86
+
87
+ it('should not be able to transfer more than balance', async () => {
88
+ await token.grantRole(ownerAddress, 'MINT')
89
+ await token.mint(receiverAddress, 100000n)
90
+ try {
91
+ await token.transfer(receiverAddress, otherReceiverAddress, 100001n)
92
+ } catch (error) {
93
+ expect(error.message).to.equal('amount exceeds balance')
94
+ }
95
+ })
96
+ })
@@ -0,0 +1,120 @@
1
+ import { expect, use } from 'chai'
2
+ import chaiAsPromised from 'chai-as-promised'
3
+ import { describe, it, beforeEach } from 'mocha'
4
+ import Validators from '../exports/validators.js'
5
+
6
+ use(chaiAsPromised)
7
+
8
+ describe('Validators', () => {
9
+ let validators
10
+ let validatorState
11
+ const tokenAddress = '0xTokenAddress'
12
+ const ownerAddress = '0xOwnerAddress'
13
+ const validatorAddress = '0xValidatorAddress'
14
+ const anotherValidatorAddress = '0xAnotherValidatorAddress'
15
+
16
+ beforeEach(() => {
17
+ global.state = {
18
+ peers: [
19
+ [ownerAddress, { bw: { up: 100, down: 100 } }],
20
+ [validatorAddress, { bw: { up: 100, down: 100 } }],
21
+ [anotherValidatorAddress, { bw: { up: 200, down: 200 } }]
22
+ ]
23
+ }
24
+ global.msg = {
25
+ sender: ownerAddress,
26
+ contract: '0xContractAddress',
27
+ staticCall: async (currency, method, args) => {
28
+ if (method === 'balanceOf') {
29
+ if (args[0] === validatorAddress) return BigInt(100000)
30
+ if (args[0] === anotherValidatorAddress) return BigInt(100000)
31
+ }
32
+ return BigInt(0)
33
+ },
34
+ call: async (currency, method, args) => {
35
+ // Mock implementation of msg.call
36
+ }
37
+ }
38
+ validators = new Validators(tokenAddress, validatorState)
39
+ })
40
+
41
+ it('should initialize with default values', () => {
42
+ expect(validators.name).to.equal('LeofcoinValidators')
43
+ expect(validators.currency).to.equal(tokenAddress)
44
+ expect(validators.validators).to.deep.equal([ownerAddress])
45
+ expect(validators.totalValidators).to.equal(1)
46
+ expect(validators.minimumBalance.toString()).to.equal(BigInt(50000).toString())
47
+ })
48
+
49
+ it('should change currency if sender is owner', () => {
50
+ validators.changeCurrency('0xNewCurrencyAddress')
51
+ expect(validators.currency).to.equal('0xNewCurrencyAddress')
52
+ })
53
+
54
+ it('should throw error if non-owner tries to change currency', () => {
55
+ global.msg.sender = validatorAddress
56
+ expect(() => validators.changeCurrency('0xNewCurrencyAddress')).to.throw('not an owner')
57
+ })
58
+
59
+ it('should add a validator if conditions are met', async () => {
60
+ await validators.addValidator(validatorAddress)
61
+ expect(validators.validators).to.include(validatorAddress)
62
+ expect(validators.totalValidators).to.equal(2)
63
+ })
64
+
65
+ it('should throw error if adding an existing validator', async () => {
66
+ await validators.addValidator(validatorAddress)
67
+ await expect(validators.addValidator(validatorAddress)).to.be.rejectedWith(
68
+ 'validator already exists'
69
+ )
70
+ })
71
+
72
+ it('should throw error if validator balance is too low', async () => {
73
+ global.msg.staticCall = async (currency, method, args) => BigInt(1000)
74
+ await expect(validators.addValidator(anotherValidatorAddress)).to.be.rejectedWith(
75
+ 'balance to low! got: 1000 need: 50000'
76
+ )
77
+ })
78
+
79
+ it('should remove a validator if conditions are met', async () => {
80
+ await validators.addValidator(validatorAddress)
81
+ await validators.removeValidator(validatorAddress)
82
+ expect(validators.validators).to.not.include(validatorAddress)
83
+ expect(validators.totalValidators).to.equal(1)
84
+ })
85
+
86
+ it('should throw error if removing a non-existing validator', async () => {
87
+ await expect(validators.removeValidator(validatorAddress)).to.be.rejectedWith(
88
+ 'validator not found'
89
+ )
90
+ })
91
+
92
+ it('should shuffle validator correctly', async () => {
93
+ validators.shuffleValidator()
94
+ expect(validators.currentValidator).to.include(ownerAddress)
95
+ await validators.removeValidator(ownerAddress)
96
+
97
+ global.msg.sender = validatorAddress
98
+ await validators.addValidator(validatorAddress)
99
+
100
+ validators.shuffleValidator()
101
+ expect(validators.currentValidator).to.include(validatorAddress)
102
+ })
103
+
104
+ it('should return the current validator', () => {
105
+ expect(validators.currentValidator).to.equal(ownerAddress)
106
+ })
107
+
108
+ it('should return state correctly', async () => {
109
+ msg.sender = validatorAddress
110
+ await validators.addValidator(validatorAddress)
111
+ validatorState = validators.state
112
+ expect(validatorState.validators).to.deep.equal([ownerAddress, validatorAddress])
113
+ })
114
+
115
+ it('should restore from state correctly', () => {
116
+ const newValidators = new Validators(tokenAddress, validatorState)
117
+ expect(newValidators.validators).to.deep.equal([ownerAddress, validatorAddress])
118
+ expect(newValidators.totalValidators).to.equal(2)
119
+ })
120
+ })
package/tsconfig.json CHANGED
@@ -6,7 +6,8 @@
6
6
  "allowJs": true,
7
7
  "allowSyntheticDefaultImports": true,
8
8
  "resolveJsonModule": true,
9
- "declaration": true
9
+ "declaration": true,
10
+ "types": ["@leofcoin/types", "@leofcoin/types/global"]
10
11
  },
11
12
  "include": ["./src/**/*"]
12
13
  }
@@ -1,8 +0,0 @@
1
- # Changesets
2
-
3
- Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4
- with multi-package repos, or single-package repos to help you version and publish your code. You can
5
- find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6
-
7
- We have a quick list of common questions to get you started engaging with this project in
8
- [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
@@ -1,11 +0,0 @@
1
- {
2
- "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
3
- "changelog": "@changesets/cli/changelog",
4
- "commit": true,
5
- "fixed": [],
6
- "linked": [],
7
- "access": "public",
8
- "baseBranch": "main",
9
- "updateInternalDependencies": "patch",
10
- "ignore": []
11
- }
package/src/types.ts DELETED
@@ -1,2 +0,0 @@
1
- import '@leofcoin/global-types'
2
-