@leofcoin/standards 0.2.9 → 0.2.11

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.
@@ -1,3 +1,4 @@
1
+ /// <reference types="@leofcoin/types/global" />
1
2
  export type ContractCreatorState = {
2
3
  contractCreator: address;
3
4
  };
@@ -1,8 +1,8 @@
1
- // when state is stored it get encoded as a string to so we need to reformat balances back to BigNumbers
1
+ // when state is stored it get encoded as a string to so we need to reformat balances back to BigInt's
2
2
  const restoreBalances = (balances) => {
3
3
  const _balances = {};
4
4
  for (const address in balances) {
5
- _balances[address] = BigNumber['from'](balances[address]);
5
+ _balances[address] = BigInt(balances[address]);
6
6
  }
7
7
  return _balances;
8
8
  };
@@ -11,7 +11,7 @@ const restoreApprovals = (approvals) => {
11
11
  for (const owner in approvals) {
12
12
  _approvals[owner] = {};
13
13
  for (const operator in approvals[owner]) {
14
- _approvals[owner][operator] = BigNumber['from'](approvals[owner][operator]);
14
+ _approvals[owner][operator] = BigInt(approvals[owner][operator]);
15
15
  }
16
16
  }
17
17
  return _approvals;
@@ -0,0 +1,37 @@
1
+ /// <reference types="@leofcoin/types/global" />
2
+ import { RolesState } from './roles.js';
3
+ import { IVoting } from './voting/interfaces/i-voting.js';
4
+ import PublicVoting from './voting/public-voting.js';
5
+ export declare interface LockState extends RolesState {
6
+ holders: bigint;
7
+ balances: {
8
+ [address: address]: bigint;
9
+ };
10
+ totalSupply: bigint;
11
+ }
12
+ export default class Lock extends PublicVoting implements IVoting {
13
+ #private;
14
+ constructor(name: string, symbol: string, decimals?: number, state?: LockState);
15
+ /**
16
+ * @return {Object} {holders, balances, ...}
17
+ */
18
+ get state(): LockState;
19
+ get totalSupply(): bigint;
20
+ get name(): string;
21
+ get symbol(): string;
22
+ get holders(): LockState['holders'];
23
+ get balances(): LockState['balances'];
24
+ get approvals(): {
25
+ [owner: string]: {
26
+ [operator: string]: bigint;
27
+ };
28
+ };
29
+ get decimals(): number;
30
+ mint(to: address, amount: bigint): void;
31
+ burn(from: address, amount: bigint): void;
32
+ balance(): any;
33
+ balanceOf(address: address): bigint;
34
+ setApproval(operator: address, amount: bigint): void;
35
+ approved(owner: address, operator: address, amount: bigint): boolean;
36
+ transfer(from: address, to: address, amount: bigint): void;
37
+ }
@@ -1,3 +1,4 @@
1
+ /// <reference types="@leofcoin/types/global" />
1
2
  import ContractCreator, { ContractCreatorState } from './contract-creator.js';
2
3
  export interface RolesState extends ContractCreatorState {
3
4
  roles: {
@@ -1,39 +1,40 @@
1
+ /// <reference types="@leofcoin/types/global" />
1
2
  import Roles, { RolesState } from './roles.js';
2
3
  export declare interface TokenState extends RolesState {
3
- holders: BigNumberish;
4
+ holders: bigint;
4
5
  balances: {
5
- [address: address]: BigNumberish;
6
+ [address: address]: bigint;
6
7
  };
7
8
  approvals: {
8
9
  [owner: address]: {
9
- [operator: address]: BigNumberish;
10
+ [operator: address]: bigint;
10
11
  };
11
12
  };
12
- totalSupply: BigNumberish;
13
+ totalSupply: bigint;
13
14
  }
14
- export default class Token extends Roles {
15
+ export default class Staking extends Roles {
15
16
  #private;
16
17
  constructor(name: string, symbol: string, decimals?: number, state?: TokenState);
17
18
  /**
18
19
  * @return {Object} {holders, balances, ...}
19
20
  */
20
21
  get state(): TokenState;
21
- get totalSupply(): BigNumberish;
22
+ get totalSupply(): bigint;
22
23
  get name(): string;
23
24
  get symbol(): string;
24
25
  get holders(): TokenState['holders'];
25
26
  get balances(): TokenState['balances'];
26
27
  get approvals(): {
27
28
  [owner: string]: {
28
- [operator: string]: import("@ethersproject/bignumber").BigNumber;
29
+ [operator: string]: bigint;
29
30
  };
30
31
  };
31
32
  get decimals(): number;
32
- mint(to: address, amount: BigNumberish): void;
33
- burn(from: address, amount: BigNumberish): void;
33
+ mint(to: address, amount: bigint): void;
34
+ burn(from: address, amount: bigint): void;
34
35
  balance(): any;
35
- balanceOf(address: address): BigNumberish;
36
- setApproval(operator: address, amount: BigNumberish): void;
37
- approved(owner: address, operator: address, amount: BigNumberish): boolean;
38
- transfer(from: address, to: address, amount: BigNumberish): void;
36
+ balanceOf(address: address): bigint;
37
+ setApproval(operator: address, amount: bigint): void;
38
+ approved(owner: address, operator: address, amount: bigint): boolean;
39
+ transfer(from: address, to: address, amount: bigint): void;
39
40
  }
@@ -1,21 +1,22 @@
1
+ /// <reference types="@leofcoin/types/global" />
1
2
  import { IVoting } from './voting/interfaces/i-voting.js';
2
3
  import PublicVoting, { PublicVotingState } from './voting/public-voting.js';
3
4
  export interface TokenReceiverState extends PublicVotingState {
4
5
  tokenToReceive: address;
5
6
  tokenReceiver: address;
6
- tokenAmountToReceive: typeof BigNumber;
7
+ tokenAmountToReceive: bigint;
7
8
  voteType: 'burn' | 'transfer';
8
9
  }
9
10
  export default class TokenReceiver extends PublicVoting implements IVoting {
10
11
  #private;
11
- constructor(tokenToReceive: address, tokenAmountToReceive: typeof BigNumber, burns: boolean, state?: TokenReceiverState);
12
+ constructor(tokenToReceive: address, tokenAmountToReceive: bigint, burns: boolean, state?: TokenReceiverState);
12
13
  get tokenToReceive(): string;
13
- get tokenAmountToReceive(): import("@ethersproject/bignumber").BigNumber;
14
+ get tokenAmountToReceive(): bigint;
14
15
  get tokenReceiver(): string;
15
16
  get state(): {
16
17
  tokenReceiver: string;
17
18
  tokenToReceive: string;
18
- tokenAmountToReceive: import("@ethersproject/bignumber").BigNumber;
19
+ tokenAmountToReceive: bigint;
19
20
  voteType: "burn" | "transfer";
20
21
  votes: {
21
22
  [id: string]: import("./voting/types.js").Vote;
@@ -42,7 +43,7 @@ export default class TokenReceiver extends PublicVoting implements IVoting {
42
43
  _burnTokenToReceive(): Promise<boolean>;
43
44
  _canPay(): Promise<any>;
44
45
  changeVoteType(type: TokenReceiverState['voteType']): Promise<void>;
45
- getTokensOut(amount: typeof BigNumber, receiver: address): void;
46
+ getTokensOut(amount: bigint, receiver: address): void;
46
47
  changeTokenAmountToReceive(): void;
47
48
  changeTokenToReceive(): Promise<void>;
48
49
  }
@@ -12,13 +12,13 @@ class TokenReceiver extends PublicVoting {
12
12
  if (state) {
13
13
  this.#tokenReceiver = state.tokenReceiver;
14
14
  this.#tokenToReceive = state.tokenToReceive;
15
- this.#tokenAmountToReceive = BigNumber['from'](state.tokenAmountToReceive);
15
+ this.#tokenAmountToReceive = BigInt(state.tokenAmountToReceive);
16
16
  this.#voteType = state.voteType;
17
17
  }
18
18
  else {
19
19
  this.#tokenReceiver = msg.contract;
20
20
  this.#tokenToReceive = tokenToReceive;
21
- this.#tokenAmountToReceive = BigNumber['from'](tokenAmountToReceive);
21
+ this.#tokenAmountToReceive = BigInt(tokenAmountToReceive);
22
22
  if (burns)
23
23
  this.#voteType = 'burn';
24
24
  }
@@ -43,7 +43,7 @@ class TokenReceiver extends PublicVoting {
43
43
  }
44
44
  async #canVote() {
45
45
  const amount = (await msg.staticCall(this.#tokenToReceive, 'balanceOf', [msg.sender]));
46
- return amount.gte(this.#tokenAmountToReceive);
46
+ return amount >= this.#tokenAmountToReceive;
47
47
  }
48
48
  /**
49
49
  * check if sender can pay
@@ -97,7 +97,7 @@ class TokenReceiver extends PublicVoting {
97
97
  async changeVoteType(type) {
98
98
  if (!this.#canVote())
99
99
  throw new Error('not a allowed');
100
- if (this.#voteType === 'transfer' && (await this.#balance()).gt(0))
100
+ if (this.#voteType === 'transfer' && (await this.#balance()) > 0n)
101
101
  throw new Error('get tokens out first or they be lost forever');
102
102
  else {
103
103
  this.createVote(`change the token amount to receive`, `set tokenAmountToReceive`, new Date().getTime() + this.votingDuration, '#changeVoteType', [type]);
@@ -123,7 +123,7 @@ class TokenReceiver extends PublicVoting {
123
123
  async changeTokenToReceive() {
124
124
  if (!this.#canVote())
125
125
  throw new Error('not a allowed');
126
- if (!(await this.#balance()).eq(0) && this.#voteType === 'transfer')
126
+ if ((await this.#balance()) > 0n && this.#voteType === 'transfer')
127
127
  throw new Error('get tokens out first or they be lost forever');
128
128
  else {
129
129
  this.createVote(`change the token to receive`, `set tokenToReceive to a new address`, new Date().getTime() + this.votingDuration, '#changeTokenToReceive', []);
@@ -1,18 +1,20 @@
1
+ /// <reference types="@leofcoin/types/global" />
1
2
  import Roles, { RolesState } from './roles.js';
2
3
  export declare interface TokenState extends RolesState {
3
4
  name: string;
4
5
  symbol: string;
5
6
  decimals: number;
6
- holders: BigNumberish;
7
+ holders: bigint;
7
8
  balances: {
8
- [address: address]: BigNumberish;
9
+ [address: address]: bigint;
9
10
  };
10
11
  approvals: {
11
12
  [owner: address]: {
12
- [operator: address]: BigNumberish;
13
+ [operator: address]: bigint;
13
14
  };
14
15
  };
15
- totalSupply: BigNumberish;
16
+ totalSupply: bigint;
17
+ maxSupply: bigint;
16
18
  }
17
19
  export default class Token extends Roles {
18
20
  #private;
@@ -21,22 +23,19 @@ export default class Token extends Roles {
21
23
  * @return {Object} {holders, balances, ...}
22
24
  */
23
25
  get state(): TokenState;
24
- get totalSupply(): BigNumberish;
25
- get name(): string;
26
- get symbol(): string;
26
+ get maxSupply(): TokenState['maxSupply'];
27
+ get totalSupply(): TokenState['totalSupply'];
28
+ get name(): TokenState['name'];
29
+ get symbol(): TokenState['symbol'];
27
30
  get holders(): TokenState['holders'];
28
31
  get balances(): TokenState['balances'];
29
- get approvals(): {
30
- [owner: string]: {
31
- [operator: string]: import("@ethersproject/bignumber").BigNumber;
32
- };
33
- };
34
- get decimals(): number;
35
- mint(to: address, amount: BigNumberish): void;
36
- burn(from: address, amount: BigNumberish): void;
32
+ get approvals(): TokenState['approvals'];
33
+ get decimals(): TokenState['decimals'];
34
+ mint(to: address, amount: bigint): void;
35
+ burn(from: address, amount: bigint): void;
37
36
  balance(): any;
38
- balanceOf(address: address): BigNumberish;
39
- setApproval(operator: address, amount: BigNumberish): void;
40
- approved(owner: address, operator: address, amount: BigNumberish): boolean;
41
- transfer(from: address, to: address, amount: BigNumberish): void;
37
+ balanceOf(address: address): bigint;
38
+ setApproval(operator: address, amount: bigint): void;
39
+ approved(owner: address, operator: address, amount: bigint): boolean;
40
+ transfer(from: address, to: address, amount: bigint): void;
42
41
  }
package/exports/token.js CHANGED
@@ -14,7 +14,7 @@ class Token extends Roles {
14
14
  /**
15
15
  * uint
16
16
  */
17
- #holders = BigNumber['from'](0);
17
+ #holders = BigInt(0);
18
18
  /**
19
19
  * Object => Object => uint
20
20
  */
@@ -24,9 +24,9 @@ class Token extends Roles {
24
24
  */
25
25
  #approvals = {};
26
26
  #decimals = 18;
27
- #totalSupply = BigNumber['from'](0);
27
+ #totalSupply = BigInt(0);
28
+ #maxSupply = BigInt(0);
28
29
  #stakingContract;
29
- // this.#privateField2 = 1
30
30
  constructor(name, symbol, decimals = 18, state) {
31
31
  if (!name)
32
32
  throw new Error(`name undefined`);
@@ -36,11 +36,12 @@ class Token extends Roles {
36
36
  if (state) {
37
37
  this.#balances = restoreBalances(state.balances);
38
38
  this.#approvals = restoreApprovals(state.approvals);
39
- this.#holders = BigNumber['from'](state.holders);
40
- this.#totalSupply = BigNumber['from'](state.totalSupply);
39
+ this.#holders = BigInt(state.holders);
40
+ this.#totalSupply = BigInt(state.totalSupply);
41
41
  this.#name = name;
42
42
  this.#symbol = symbol;
43
43
  this.#decimals = decimals;
44
+ this.#maxSupply = BigInt(state.maxSupply);
44
45
  }
45
46
  else {
46
47
  this.#name = name;
@@ -51,6 +52,7 @@ class Token extends Roles {
51
52
  // enables snapshotting
52
53
  // needs dev attention so nothing breaks after snapshot happens
53
54
  // iow everything that is not static needs to be included in the stateObject
55
+ // TODO: implement snapshotting test
54
56
  /**
55
57
  * @return {Object} {holders, balances, ...}
56
58
  */
@@ -63,9 +65,13 @@ class Token extends Roles {
63
65
  holders: this.holders,
64
66
  balances: this.balances,
65
67
  approvals: { ...this.#approvals },
66
- totalSupply: this.totalSupply
68
+ totalSupply: this.totalSupply,
69
+ maxSupply: this.#maxSupply
67
70
  };
68
71
  }
72
+ get maxSupply() {
73
+ return this.#maxSupply;
74
+ }
69
75
  get totalSupply() {
70
76
  return this.#totalSupply;
71
77
  }
@@ -90,31 +96,46 @@ class Token extends Roles {
90
96
  mint(to, amount) {
91
97
  if (!this.hasRole(msg.sender, 'MINT'))
92
98
  throw new Error('not allowed');
93
- this.#totalSupply = this.#totalSupply.add(amount);
94
- this.#increaseBalance(to, amount);
99
+ const supply = this.#totalSupply + amount;
100
+ if (this.#maxSupply === 0n) {
101
+ this.#totalSupply = supply;
102
+ this.#increaseBalance(to, amount);
103
+ }
104
+ else {
105
+ if (supply <= this.#maxSupply) {
106
+ this.#totalSupply = supply;
107
+ this.#increaseBalance(to, amount);
108
+ }
109
+ else {
110
+ throw new Error('amount exceeds max supply');
111
+ }
112
+ }
95
113
  }
96
114
  burn(from, amount) {
97
115
  if (!this.hasRole(msg.sender, 'BURN') || msg.sender !== from)
98
116
  throw new Error('not allowed');
99
- const total = this.#totalSupply.sub(amount);
100
- if (total.gte(0)) {
117
+ const total = this.#totalSupply - amount;
118
+ if (total >= 0) {
101
119
  this.#totalSupply = total;
102
120
  this.#decreaseBalance(from, amount);
103
121
  }
122
+ else {
123
+ throw new Error('amount exceeds total supply');
124
+ }
104
125
  }
105
126
  #beforeTransfer(from, to, amount) {
106
127
  if (!this.#balances[from] || this.#balances[from] < amount)
107
128
  throw new Error('amount exceeds balance');
108
129
  }
109
130
  #updateHolders(address, previousBalance) {
110
- if (this.#balances[address].toHexString() === '0x00')
111
- this.#holders.sub(1);
112
- else if (this.#balances[address].toHexString() !== '0x00' && previousBalance.toHexString() === '0x00')
113
- this.#holders.add(1);
131
+ if (this.#balances[address] === 0n)
132
+ this.#holders -= 1n;
133
+ else if (this.#balances[address] !== 0n && previousBalance === 0n)
134
+ this.#holders += 1n;
114
135
  }
115
136
  #increaseBalance(address, amount) {
116
137
  if (!this.#balances[address])
117
- this.#balances[address] = BigNumber['from'](0);
138
+ this.#balances[address] = BigInt(0);
118
139
  const previousBalance = this.#balances[address];
119
140
  this.#balances[address] = this.#balances[address].add(amount);
120
141
  this.#updateHolders(address, previousBalance);
@@ -134,14 +155,14 @@ class Token extends Roles {
134
155
  const owner = msg.sender;
135
156
  if (!this.#approvals[owner])
136
157
  this.#approvals[owner] = {};
137
- this.#approvals[owner][operator] = BigNumber['from'](amount);
158
+ this.#approvals[owner][operator] = BigInt(amount);
138
159
  }
139
160
  approved(owner, operator, amount) {
140
161
  return this.#approvals[owner][operator] === amount;
141
162
  }
142
163
  transfer(from, to, amount) {
143
- // TODO: is BigNumber?
144
- amount = BigNumber['from'](amount);
164
+ // TODO: is bigint?
165
+ amount = BigInt(amount);
145
166
  this.#beforeTransfer(from, to, amount);
146
167
  this.#decreaseBalance(from, amount);
147
168
  this.#increaseBalance(to, amount);
@@ -1,3 +1,4 @@
1
+ /// <reference types="@leofcoin/types/global" />
1
2
  import { ContractCreatorState } from '../contract-creator.js';
2
3
  import { IVoting } from './interfaces/i-voting.js';
3
4
  import { VotingState } from './types.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/standards",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "description": "Contract standards",
5
5
  "type": "module",
6
6
  "exports": {
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "scripts": {
50
50
  "build": "rollup -c",
51
- "test": "echo \"Error: no test specified\" && exit 1"
51
+ "test": "mocha --require ts-node/register test/**/*.ts"
52
52
  },
53
53
  "repository": {
54
54
  "type": "git",
@@ -62,13 +62,11 @@
62
62
  },
63
63
  "homepage": "https://github.com/ArteonToken/standards#readme",
64
64
  "devDependencies": {
65
- "@changesets/cli": "^2.27.7",
66
- "@leofcoin/global-types": "^1.0.0",
65
+ "@leofcoin/types": "^1.0.17",
67
66
  "@rollup/plugin-typescript": "^11.1.6",
68
- "rollup": "^4.12.0",
69
- "tslib": "^2.5.0"
70
- },
71
- "dependencies": {
72
- "@ethersproject/bignumber": "^5.7.0"
67
+ "chai": "^5.1.1",
68
+ "mocha": "^10.7.3",
69
+ "rollup": "^4.22.1",
70
+ "tslib": "^2.7.0"
73
71
  }
74
72
  }
package/src/helpers.ts CHANGED
@@ -1,8 +1,8 @@
1
- // when state is stored it get encoded as a string to so we need to reformat balances back to BigNumbers
1
+ // when state is stored it get encoded as a string to so we need to reformat balances back to BigInt's
2
2
  export const restoreBalances = (balances) => {
3
3
  const _balances = {}
4
4
  for (const address in balances) {
5
- _balances[address] = BigNumber['from'](balances[address])
5
+ _balances[address] = BigInt(balances[address])
6
6
  }
7
7
  return _balances
8
8
  }
@@ -12,7 +12,7 @@ export const restoreApprovals = (approvals) => {
12
12
  for (const owner in approvals) {
13
13
  _approvals[owner] = {}
14
14
  for (const operator in approvals[owner]) {
15
- _approvals[owner][operator] = BigNumber['from'](approvals[owner][operator])
15
+ _approvals[owner][operator] = BigInt(approvals[owner][operator])
16
16
  }
17
17
  }
18
18
  return _approvals
@@ -0,0 +1,3 @@
1
+ export interface IToken {
2
+
3
+ }
package/src/lock.ts CHANGED
@@ -1,13 +1,15 @@
1
1
  import { restoreApprovals, restoreBalances } from './helpers.js'
2
2
  import Roles, { RolesState } from './roles.js'
3
+ import { IVoting } from './voting/interfaces/i-voting.js'
4
+ import PublicVoting from './voting/public-voting.js'
3
5
 
4
6
  export declare interface LockState extends RolesState {
5
- holders: BigNumberish
6
- balances: { [address: address]: BigNumberish }
7
- totalSupply: BigNumberish
7
+ holders: bigint
8
+ balances: { [address: address]: bigint }
9
+ totalSupply: bigint
8
10
  }
9
11
 
10
- export default class Lock extends PublicVoting {
12
+ export default class Lock extends PublicVoting implements IVoting {
11
13
  /**
12
14
  * string
13
15
  */
@@ -19,7 +21,7 @@ export default class Lock extends PublicVoting {
19
21
  /**
20
22
  * uint
21
23
  */
22
- #holders: typeof BigNumber = BigNumber['from'](0)
24
+ #holders: bigint = BigInt(0)
23
25
  /**
24
26
  * Object => Object => uint
25
27
  */
@@ -27,16 +29,16 @@ export default class Lock extends PublicVoting {
27
29
  /**
28
30
  * Object => Object => uint
29
31
  */
30
- #approvals: { [owner: string]: { [operator: string]: typeof BigNumber } } = {}
32
+ #approvals: { [owner: string]: { [operator: string]: bigint } } = {}
31
33
 
32
34
  #decimals = 18
33
35
 
34
- #totalSupply: typeof BigNumber = BigNumber['from'](0)
36
+ #totalSupply: bigint = BigInt(0)
35
37
 
36
38
  #stakingContract: address
37
39
 
38
40
  // this.#privateField2 = 1
39
- constructor(name: string, symbol: string, decimals: number = 18, state?: TokenState) {
41
+ constructor(name: string, symbol: string, decimals: number = 18, state?: LockState) {
40
42
  if (!name) throw new Error(`name undefined`)
41
43
  if (!symbol) throw new Error(`symbol undefined`)
42
44
 
@@ -45,8 +47,8 @@ export default class Lock extends PublicVoting {
45
47
  if (state) {
46
48
  this.#balances = restoreBalances(state.balances)
47
49
  this.#approvals = restoreApprovals(state.approvals)
48
- this.#holders = BigNumber['from'](state.holders)
49
- this.#totalSupply = BigNumber['from'](state.totalSupply)
50
+ this.#holders = BigInt(state.holders)
51
+ this.#totalSupply = BigInt(state.totalSupply)
50
52
  } else {
51
53
  this.#name = name
52
54
  this.#symbol = symbol
@@ -60,7 +62,7 @@ export default class Lock extends PublicVoting {
60
62
  /**
61
63
  * @return {Object} {holders, balances, ...}
62
64
  */
63
- get state(): TokenState {
65
+ get state(): LockState {
64
66
  return {
65
67
  ...super.state,
66
68
  holders: this.holders,
@@ -70,7 +72,7 @@ export default class Lock extends PublicVoting {
70
72
  }
71
73
  }
72
74
 
73
- get totalSupply(): BigNumberish {
75
+ get totalSupply(): bigint {
74
76
  return this.#totalSupply
75
77
  }
76
78
 
@@ -82,11 +84,11 @@ export default class Lock extends PublicVoting {
82
84
  return this.#symbol
83
85
  }
84
86
 
85
- get holders(): TokenState['holders'] {
87
+ get holders(): LockState['holders'] {
86
88
  return this.#holders
87
89
  }
88
90
 
89
- get balances(): TokenState['balances'] {
91
+ get balances(): LockState['balances'] {
90
92
  return { ...this.#balances }
91
93
  }
92
94
 
@@ -98,41 +100,40 @@ export default class Lock extends PublicVoting {
98
100
  return this.#decimals
99
101
  }
100
102
 
101
- mint(to: address, amount: BigNumberish) {
103
+ mint(to: address, amount: bigint) {
102
104
  if (!this.hasRole(msg.sender, 'MINT')) throw new Error('not allowed')
103
105
 
104
- this.#totalSupply = this.#totalSupply.add(amount)
106
+ this.#totalSupply = this.#totalSupply + amount
105
107
  this.#increaseBalance(to, amount)
106
108
  }
107
109
 
108
- burn(from: address, amount: BigNumberish) {
110
+ burn(from: address, amount: bigint) {
109
111
  if (!this.hasRole(msg.sender, 'BURN') || msg.sender !== from) throw new Error('not allowed')
110
- const total = this.#totalSupply.sub(amount)
111
- if (total.gte(0)) {
112
+ const total = this.#totalSupply - amount
113
+ if (total > 0n) {
112
114
  this.#totalSupply = total
113
115
  this.#decreaseBalance(from, amount)
114
116
  }
115
117
  }
116
118
 
117
- #beforeTransfer(from: address, to: address, amount: BigNumberish) {
119
+ #beforeTransfer(from: address, to: address, amount: bigint) {
118
120
  if (!this.#balances[from] || this.#balances[from] < amount) throw new Error('amount exceeds balance')
119
121
  }
120
122
 
121
- #updateHolders(address: address, previousBalance: typeof BigNumber) {
122
- if (this.#balances[address].toHexString() === '0x00') this.#holders.sub(1)
123
- else if (this.#balances[address].toHexString() !== '0x00' && previousBalance.toHexString() === '0x00')
124
- this.#holders.add(1)
123
+ #updateHolders(address: address, previousBalance: bigint) {
124
+ if (this.#balances[address] === 0n) this.#holders -= 1n
125
+ else if (this.#balances[address] !== 0n && previousBalance === 0n) this.#holders += 1n
125
126
  }
126
127
 
127
- #increaseBalance(address: address, amount: BigNumberish) {
128
- if (!this.#balances[address]) this.#balances[address] = BigNumber['from'](0)
128
+ #increaseBalance(address: address, amount: bigint) {
129
+ if (!this.#balances[address]) this.#balances[address] = BigInt(0)
129
130
  const previousBalance = this.#balances[address]
130
131
 
131
132
  this.#balances[address] = this.#balances[address].add(amount)
132
133
  this.#updateHolders(address, previousBalance)
133
134
  }
134
135
 
135
- #decreaseBalance(address: address, amount: BigNumberish) {
136
+ #decreaseBalance(address: address, amount: bigint) {
136
137
  const previousBalance = this.#balances[address]
137
138
  this.#balances[address] = this.#balances[address].sub(amount)
138
139
  this.#updateHolders(address, previousBalance)
@@ -142,23 +143,23 @@ export default class Lock extends PublicVoting {
142
143
  return this.#balances[msg.sender]
143
144
  }
144
145
 
145
- balanceOf(address: address): BigNumberish {
146
+ balanceOf(address: address): bigint {
146
147
  return this.#balances[address]
147
148
  }
148
149
 
149
- setApproval(operator: address, amount: BigNumberish) {
150
+ setApproval(operator: address, amount: bigint) {
150
151
  const owner = msg.sender
151
152
  if (!this.#approvals[owner]) this.#approvals[owner] = {}
152
- this.#approvals[owner][operator] = BigNumber['from'](amount)
153
+ this.#approvals[owner][operator] = BigInt(amount)
153
154
  }
154
155
 
155
- approved(owner: address, operator: address, amount: BigNumberish): boolean {
156
+ approved(owner: address, operator: address, amount: bigint): boolean {
156
157
  return this.#approvals[owner][operator] === amount
157
158
  }
158
159
 
159
- transfer(from: address, to: address, amount: BigNumberish) {
160
+ transfer(from: address, to: address, amount: bigint) {
160
161
  // TODO: is BigNumber?
161
- amount = BigNumber['from'](amount)
162
+ amount = BigInt(amount)
162
163
  this.#beforeTransfer(from, to, amount)
163
164
  this.#decreaseBalance(from, amount)
164
165
  this.#increaseBalance(to, amount)
package/src/staking.ts CHANGED
@@ -2,10 +2,10 @@ import { restoreApprovals, restoreBalances } from './helpers.js'
2
2
  import Roles, { RolesState } from './roles.js'
3
3
 
4
4
  export declare interface TokenState extends RolesState {
5
- holders: BigNumberish
6
- balances: { [address: address]: BigNumberish }
7
- approvals: { [owner: address]: { [operator: address]: BigNumberish } }
8
- totalSupply: BigNumberish
5
+ holders: bigint
6
+ balances: { [address: address]: bigint }
7
+ approvals: { [owner: address]: { [operator: address]: bigint } }
8
+ totalSupply: bigint
9
9
  }
10
10
 
11
11
  export default class Staking extends Roles {
@@ -20,7 +20,7 @@ export default class Staking extends Roles {
20
20
  /**
21
21
  * uint
22
22
  */
23
- #holders: typeof BigNumber = BigNumber['from'](0)
23
+ #holders: bigint = BigInt(0)
24
24
  /**
25
25
  * Object => Object => uint
26
26
  */
@@ -28,11 +28,11 @@ export default class Staking extends Roles {
28
28
  /**
29
29
  * Object => Object => uint
30
30
  */
31
- #approvals: { [owner: string]: { [operator: string]: typeof BigNumber } } = {}
31
+ #approvals: { [owner: string]: { [operator: string]: bigint } } = {}
32
32
 
33
33
  #decimals = 18
34
34
 
35
- #totalSupply: typeof BigNumber = BigNumber['from'](0)
35
+ #totalSupply: bigint = BigInt(0)
36
36
 
37
37
  #stakingContract: address
38
38
 
@@ -46,8 +46,8 @@ export default class Staking extends Roles {
46
46
  if (state) {
47
47
  this.#balances = restoreBalances(state.balances)
48
48
  this.#approvals = restoreApprovals(state.approvals)
49
- this.#holders = BigNumber['from'](state.holders)
50
- this.#totalSupply = BigNumber['from'](state.totalSupply)
49
+ this.#holders = BigInt(state.holders)
50
+ this.#totalSupply = BigInt(state.totalSupply)
51
51
  } else {
52
52
  this.#name = name
53
53
  this.#symbol = symbol
@@ -71,7 +71,7 @@ export default class Staking extends Roles {
71
71
  }
72
72
  }
73
73
 
74
- get totalSupply(): BigNumberish {
74
+ get totalSupply(): bigint {
75
75
  return this.#totalSupply
76
76
  }
77
77
 
@@ -99,41 +99,40 @@ export default class Staking extends Roles {
99
99
  return this.#decimals
100
100
  }
101
101
 
102
- mint(to: address, amount: BigNumberish) {
102
+ mint(to: address, amount: bigint) {
103
103
  if (!this.hasRole(msg.sender, 'MINT')) throw new Error('not allowed')
104
104
 
105
- this.#totalSupply = this.#totalSupply.add(amount)
105
+ this.#totalSupply = this.#totalSupply + amount
106
106
  this.#increaseBalance(to, amount)
107
107
  }
108
108
 
109
- burn(from: address, amount: BigNumberish) {
109
+ burn(from: address, amount: bigint) {
110
110
  if (!this.hasRole(msg.sender, 'BURN') || msg.sender !== from) throw new Error('not allowed')
111
- const total = this.#totalSupply.sub(amount)
112
- if (total.gte(0)) {
111
+ const total = this.#totalSupply - amount
112
+ if (total > 0n) {
113
113
  this.#totalSupply = total
114
114
  this.#decreaseBalance(from, amount)
115
115
  }
116
116
  }
117
117
 
118
- #beforeTransfer(from: address, to: address, amount: BigNumberish) {
118
+ #beforeTransfer(from: address, to: address, amount: bigint) {
119
119
  if (!this.#balances[from] || this.#balances[from] < amount) throw new Error('amount exceeds balance')
120
120
  }
121
121
 
122
- #updateHolders(address: address, previousBalance: typeof BigNumber) {
123
- if (this.#balances[address].toHexString() === '0x00') this.#holders.sub(1)
124
- else if (this.#balances[address].toHexString() !== '0x00' && previousBalance.toHexString() === '0x00')
125
- this.#holders.add(1)
122
+ #updateHolders(address: address, previousBalance: bigint) {
123
+ if (this.#balances[address] === 0n) this.#holders -= 1n
124
+ else if (this.#balances[address] !== 0n && previousBalance === 0n) this.#holders += 1n
126
125
  }
127
126
 
128
- #increaseBalance(address: address, amount: BigNumberish) {
129
- if (!this.#balances[address]) this.#balances[address] = BigNumber['from'](0)
127
+ #increaseBalance(address: address, amount: bigint) {
128
+ if (!this.#balances[address]) this.#balances[address] = BigInt(0)
130
129
  const previousBalance = this.#balances[address]
131
130
 
132
131
  this.#balances[address] = this.#balances[address].add(amount)
133
132
  this.#updateHolders(address, previousBalance)
134
133
  }
135
134
 
136
- #decreaseBalance(address: address, amount: BigNumberish) {
135
+ #decreaseBalance(address: address, amount: bigint) {
137
136
  const previousBalance = this.#balances[address]
138
137
  this.#balances[address] = this.#balances[address].sub(amount)
139
138
  this.#updateHolders(address, previousBalance)
@@ -143,23 +142,23 @@ export default class Staking extends Roles {
143
142
  return this.#balances[msg.sender]
144
143
  }
145
144
 
146
- balanceOf(address: address): BigNumberish {
145
+ balanceOf(address: address): bigint {
147
146
  return this.#balances[address]
148
147
  }
149
148
 
150
- setApproval(operator: address, amount: BigNumberish) {
149
+ setApproval(operator: address, amount: bigint) {
151
150
  const owner = msg.sender
152
151
  if (!this.#approvals[owner]) this.#approvals[owner] = {}
153
- this.#approvals[owner][operator] = BigNumber['from'](amount)
152
+ this.#approvals[owner][operator] = BigInt(amount)
154
153
  }
155
154
 
156
- approved(owner: address, operator: address, amount: BigNumberish): boolean {
155
+ approved(owner: address, operator: address, amount: bigint): boolean {
157
156
  return this.#approvals[owner][operator] === amount
158
157
  }
159
158
 
160
- transfer(from: address, to: address, amount: BigNumberish) {
159
+ transfer(from: address, to: address, amount: bigint) {
161
160
  // TODO: is BigNumber?
162
- amount = BigNumber['from'](amount)
161
+ amount = BigInt(amount)
163
162
  this.#beforeTransfer(from, to, amount)
164
163
  this.#decreaseBalance(from, amount)
165
164
  this.#increaseBalance(to, amount)
@@ -4,31 +4,26 @@ import PublicVoting, { PublicVotingState } from './voting/public-voting.js'
4
4
  export interface TokenReceiverState extends PublicVotingState {
5
5
  tokenToReceive: address
6
6
  tokenReceiver: address
7
- tokenAmountToReceive: typeof BigNumber
7
+ tokenAmountToReceive: bigint
8
8
  voteType: 'burn' | 'transfer'
9
9
  }
10
10
  export default class TokenReceiver extends PublicVoting implements IVoting {
11
11
  #tokenToReceive: address
12
- #tokenAmountToReceive: typeof BigNumber
12
+ #tokenAmountToReceive: bigint
13
13
  #tokenReceiver: address
14
14
  #voteType: TokenReceiverState['voteType'] = 'transfer'
15
15
 
16
- constructor(
17
- tokenToReceive: address,
18
- tokenAmountToReceive: typeof BigNumber,
19
- burns: boolean,
20
- state?: TokenReceiverState
21
- ) {
16
+ constructor(tokenToReceive: address, tokenAmountToReceive: bigint, burns: boolean, state?: TokenReceiverState) {
22
17
  super(state)
23
18
  if (state) {
24
19
  this.#tokenReceiver = state.tokenReceiver
25
20
  this.#tokenToReceive = state.tokenToReceive
26
- this.#tokenAmountToReceive = BigNumber['from'](state.tokenAmountToReceive)
21
+ this.#tokenAmountToReceive = BigInt(state.tokenAmountToReceive)
27
22
  this.#voteType = state.voteType
28
23
  } else {
29
24
  this.#tokenReceiver = msg.contract
30
25
  this.#tokenToReceive = tokenToReceive
31
- this.#tokenAmountToReceive = BigNumber['from'](tokenAmountToReceive)
26
+ this.#tokenAmountToReceive = BigInt(tokenAmountToReceive)
32
27
  if (burns) this.#voteType = 'burn'
33
28
  }
34
29
  }
@@ -56,8 +51,8 @@ export default class TokenReceiver extends PublicVoting implements IVoting {
56
51
  }
57
52
 
58
53
  async #canVote() {
59
- const amount = (await msg.staticCall(this.#tokenToReceive, 'balanceOf', [msg.sender])) as typeof BigNumber
60
- return amount.gte(this.#tokenAmountToReceive)
54
+ const amount = (await msg.staticCall(this.#tokenToReceive, 'balanceOf', [msg.sender])) as bigint
55
+ return amount >= this.#tokenAmountToReceive
61
56
  }
62
57
 
63
58
  /**
@@ -106,7 +101,7 @@ export default class TokenReceiver extends PublicVoting implements IVoting {
106
101
  this.#tokenToReceive = address
107
102
  }
108
103
 
109
- #changeTokenAmountToReceive(amount: typeof BigNumber) {
104
+ #changeTokenAmountToReceive(amount: bigint) {
110
105
  this.#tokenAmountToReceive = amount
111
106
  }
112
107
 
@@ -114,13 +109,13 @@ export default class TokenReceiver extends PublicVoting implements IVoting {
114
109
  this.#voteType = type
115
110
  }
116
111
 
117
- #getTokensOut(amount: typeof BigNumber, receiver: address) {
112
+ #getTokensOut(amount: bigint, receiver: address) {
118
113
  return msg.call(this.#tokenReceiver, 'transfer', [this.#tokenReceiver, receiver, amount])
119
114
  }
120
115
 
121
116
  async changeVoteType(type: TokenReceiverState['voteType']) {
122
117
  if (!this.#canVote()) throw new Error('not a allowed')
123
- if (this.#voteType === 'transfer' && (await this.#balance()).gt(0))
118
+ if (this.#voteType === 'transfer' && (await this.#balance()) > 0n)
124
119
  throw new Error('get tokens out first or they be lost forever')
125
120
  else {
126
121
  this.createVote(
@@ -133,7 +128,7 @@ export default class TokenReceiver extends PublicVoting implements IVoting {
133
128
  }
134
129
  }
135
130
 
136
- getTokensOut(amount: typeof BigNumber, receiver: address) {
131
+ getTokensOut(amount: bigint, receiver: address) {
137
132
  if (!this.#canVote()) throw new Error('not a allowed')
138
133
  else {
139
134
  this.createVote(
@@ -159,13 +154,13 @@ export default class TokenReceiver extends PublicVoting implements IVoting {
159
154
  }
160
155
  }
161
156
 
162
- #balance(): Promise<typeof BigNumber> {
157
+ #balance(): Promise<bigint> {
163
158
  return msg.staticCall(this.#tokenToReceive, 'balanceOf', [this.#tokenReceiver])
164
159
  }
165
160
 
166
161
  async changeTokenToReceive() {
167
162
  if (!this.#canVote()) throw new Error('not a allowed')
168
- if (!(await this.#balance()).eq(0) && this.#voteType === 'transfer')
163
+ if ((await this.#balance()) > 0n && this.#voteType === 'transfer')
169
164
  throw new Error('get tokens out first or they be lost forever')
170
165
  else {
171
166
  this.createVote(
package/src/token.ts CHANGED
@@ -5,10 +5,11 @@ export declare interface TokenState extends RolesState {
5
5
  name: string
6
6
  symbol: string
7
7
  decimals: number
8
- holders: BigNumberish
9
- balances: { [address: address]: BigNumberish }
10
- approvals: { [owner: address]: { [operator: address]: BigNumberish } }
11
- totalSupply: BigNumberish
8
+ holders: bigint
9
+ balances: { [address: address]: bigint }
10
+ approvals: { [owner: address]: { [operator: address]: bigint } }
11
+ totalSupply: bigint
12
+ maxSupply: bigint // 0 for unlimited
12
13
  }
13
14
 
14
15
  export default class Token extends Roles {
@@ -23,7 +24,7 @@ export default class Token extends Roles {
23
24
  /**
24
25
  * uint
25
26
  */
26
- #holders: typeof BigNumber = BigNumber['from'](0)
27
+ #holders: bigint = BigInt(0)
27
28
  /**
28
29
  * Object => Object => uint
29
30
  */
@@ -31,15 +32,16 @@ export default class Token extends Roles {
31
32
  /**
32
33
  * Object => Object => uint
33
34
  */
34
- #approvals: { [owner: string]: { [operator: string]: typeof BigNumber } } = {}
35
+ #approvals: { [owner: string]: { [operator: string]: bigint } } = {}
35
36
 
36
37
  #decimals = 18
37
38
 
38
- #totalSupply: typeof BigNumber = BigNumber['from'](0)
39
+ #totalSupply: bigint = BigInt(0)
40
+
41
+ #maxSupply: bigint = BigInt(0)
39
42
 
40
43
  #stakingContract: address
41
44
 
42
- // this.#privateField2 = 1
43
45
  constructor(name: string, symbol: string, decimals: number = 18, state?: TokenState) {
44
46
  if (!name) throw new Error(`name undefined`)
45
47
  if (!symbol) throw new Error(`symbol undefined`)
@@ -49,11 +51,12 @@ export default class Token extends Roles {
49
51
  if (state) {
50
52
  this.#balances = restoreBalances(state.balances)
51
53
  this.#approvals = restoreApprovals(state.approvals)
52
- this.#holders = BigNumber['from'](state.holders)
53
- this.#totalSupply = BigNumber['from'](state.totalSupply)
54
+ this.#holders = BigInt(state.holders)
55
+ this.#totalSupply = BigInt(state.totalSupply)
54
56
  this.#name = name
55
57
  this.#symbol = symbol
56
58
  this.#decimals = decimals
59
+ this.#maxSupply = BigInt(state.maxSupply)
57
60
  } else {
58
61
  this.#name = name
59
62
  this.#symbol = symbol
@@ -64,6 +67,7 @@ export default class Token extends Roles {
64
67
  // enables snapshotting
65
68
  // needs dev attention so nothing breaks after snapshot happens
66
69
  // iow everything that is not static needs to be included in the stateObject
70
+ // TODO: implement snapshotting test
67
71
  /**
68
72
  * @return {Object} {holders, balances, ...}
69
73
  */
@@ -76,19 +80,24 @@ export default class Token extends Roles {
76
80
  holders: this.holders,
77
81
  balances: this.balances,
78
82
  approvals: { ...this.#approvals },
79
- totalSupply: this.totalSupply
83
+ totalSupply: this.totalSupply,
84
+ maxSupply: this.#maxSupply
80
85
  }
81
86
  }
82
87
 
83
- get totalSupply(): BigNumberish {
88
+ get maxSupply(): TokenState['maxSupply'] {
89
+ return this.#maxSupply
90
+ }
91
+
92
+ get totalSupply(): TokenState['totalSupply'] {
84
93
  return this.#totalSupply
85
94
  }
86
95
 
87
- get name(): string {
96
+ get name(): TokenState['name'] {
88
97
  return this.#name
89
98
  }
90
99
 
91
- get symbol(): string {
100
+ get symbol(): TokenState['symbol'] {
92
101
  return this.#symbol
93
102
  }
94
103
 
@@ -100,49 +109,60 @@ export default class Token extends Roles {
100
109
  return { ...this.#balances }
101
110
  }
102
111
 
103
- get approvals() {
112
+ get approvals(): TokenState['approvals'] {
104
113
  return this.#approvals
105
114
  }
106
115
 
107
- get decimals() {
116
+ get decimals(): TokenState['decimals'] {
108
117
  return this.#decimals
109
118
  }
110
119
 
111
- mint(to: address, amount: BigNumberish) {
120
+ mint(to: address, amount: bigint) {
112
121
  if (!this.hasRole(msg.sender, 'MINT')) throw new Error('not allowed')
113
122
 
114
- this.#totalSupply = this.#totalSupply.add(amount)
115
- this.#increaseBalance(to, amount)
123
+ const supply = this.#totalSupply + amount
124
+ if (this.#maxSupply === 0n) {
125
+ this.#totalSupply = supply
126
+ this.#increaseBalance(to, amount)
127
+ } else {
128
+ if (supply <= this.#maxSupply) {
129
+ this.#totalSupply = supply
130
+ this.#increaseBalance(to, amount)
131
+ } else {
132
+ throw new Error('amount exceeds max supply')
133
+ }
134
+ }
116
135
  }
117
136
 
118
- burn(from: address, amount: BigNumberish) {
137
+ burn(from: address, amount: bigint) {
119
138
  if (!this.hasRole(msg.sender, 'BURN') || msg.sender !== from) throw new Error('not allowed')
120
- const total = this.#totalSupply.sub(amount)
121
- if (total.gte(0)) {
139
+ const total = this.#totalSupply - amount
140
+ if (total >= 0) {
122
141
  this.#totalSupply = total
123
142
  this.#decreaseBalance(from, amount)
143
+ } else {
144
+ throw new Error('amount exceeds total supply')
124
145
  }
125
146
  }
126
147
 
127
- #beforeTransfer(from: address, to: address, amount: BigNumberish) {
148
+ #beforeTransfer(from: address, to: address, amount: bigint) {
128
149
  if (!this.#balances[from] || this.#balances[from] < amount) throw new Error('amount exceeds balance')
129
150
  }
130
151
 
131
- #updateHolders(address: address, previousBalance: typeof BigNumber) {
132
- if (this.#balances[address].toHexString() === '0x00') this.#holders.sub(1)
133
- else if (this.#balances[address].toHexString() !== '0x00' && previousBalance.toHexString() === '0x00')
134
- this.#holders.add(1)
152
+ #updateHolders(address: address, previousBalance: bigint) {
153
+ if (this.#balances[address] === 0n) this.#holders -= 1n
154
+ else if (this.#balances[address] !== 0n && previousBalance === 0n) this.#holders += 1n
135
155
  }
136
156
 
137
- #increaseBalance(address: address, amount: BigNumberish) {
138
- if (!this.#balances[address]) this.#balances[address] = BigNumber['from'](0)
157
+ #increaseBalance(address: address, amount: bigint) {
158
+ if (!this.#balances[address]) this.#balances[address] = BigInt(0)
139
159
  const previousBalance = this.#balances[address]
140
160
 
141
161
  this.#balances[address] = this.#balances[address].add(amount)
142
162
  this.#updateHolders(address, previousBalance)
143
163
  }
144
164
 
145
- #decreaseBalance(address: address, amount: BigNumberish) {
165
+ #decreaseBalance(address: address, amount: bigint) {
146
166
  const previousBalance = this.#balances[address]
147
167
  this.#balances[address] = this.#balances[address].sub(amount)
148
168
  this.#updateHolders(address, previousBalance)
@@ -152,23 +172,23 @@ export default class Token extends Roles {
152
172
  return this.#balances[msg.sender]
153
173
  }
154
174
 
155
- balanceOf(address: address): BigNumberish {
175
+ balanceOf(address: address): bigint {
156
176
  return this.#balances[address]
157
177
  }
158
178
 
159
- setApproval(operator: address, amount: BigNumberish) {
179
+ setApproval(operator: address, amount: bigint) {
160
180
  const owner = msg.sender
161
181
  if (!this.#approvals[owner]) this.#approvals[owner] = {}
162
- this.#approvals[owner][operator] = BigNumber['from'](amount)
182
+ this.#approvals[owner][operator] = BigInt(amount)
163
183
  }
164
184
 
165
- approved(owner: address, operator: address, amount: BigNumberish): boolean {
185
+ approved(owner: address, operator: address, amount: bigint): boolean {
166
186
  return this.#approvals[owner][operator] === amount
167
187
  }
168
188
 
169
- transfer(from: address, to: address, amount: BigNumberish) {
170
- // TODO: is BigNumber?
171
- amount = BigNumber['from'](amount)
189
+ transfer(from: address, to: address, amount: bigint) {
190
+ // TODO: is bigint?
191
+ amount = BigInt(amount)
172
192
  this.#beforeTransfer(from, to, amount)
173
193
  this.#decreaseBalance(from, amount)
174
194
  this.#increaseBalance(to, amount)
package/tsconfig.json CHANGED
@@ -5,7 +5,8 @@
5
5
  "outDir": "./exports",
6
6
  "moduleResolution": "NodeNext",
7
7
  "declaration": true,
8
- "declarationDir": "./exports"
8
+ "declarationDir": "./exports",
9
+ "types": ["@leofcoin/types/global"]
9
10
  },
10
- "include": ["./src/*", "./node_modules/@leofcoin/global-types/*"]
11
+ "include": ["./src/*"]
11
12
  }