@leofcoin/contracts 0.1.14 → 0.1.15
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/.github/workflows/test.yml +33 -0
- package/.prettierrc +11 -11
- package/.size-log.json +115 -0
- package/LICENSE +20 -20
- package/exports/factory.d.ts +6 -3
- package/exports/factory.js +1 -1
- package/exports/name-service.js +1 -1
- package/exports/native-token.d.ts +2 -2
- package/exports/native-token.js +1 -1
- package/exports/power-token.d.ts +1 -2
- package/exports/power-token.js +1 -1
- package/exports/validators.d.ts +2 -5
- package/exports/validators.js +1 -1
- package/package.json +42 -43
- package/rollup.config.js +86 -86
- package/scripts/track-size.js +129 -0
- package/src/chat.ts +25 -25
- package/src/factory.ts +79 -73
- package/src/name-service.ts +93 -92
- package/src/native-token.ts +13 -8
- package/src/power-token.ts +7 -8
- package/src/validators.ts +148 -147
- package/test/factory.js +65 -66
- package/test/native-token.js +86 -96
- package/test/validators.js +119 -120
- package/tsconfig.json +14 -13
package/test/native-token.js
CHANGED
|
@@ -1,96 +1,86 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import Leofcoin from './../exports/native-token.js'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
token
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it('should
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
await token.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
})
|
|
1
|
+
import { describe, it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import Leofcoin from './../exports/native-token.js'
|
|
4
|
+
|
|
5
|
+
describe('Leofcoin', () => {
|
|
6
|
+
let token
|
|
7
|
+
const receiverAddress = '0xReceiverAddress'
|
|
8
|
+
const otherReceiverAddress = '0xOtherReceiverAddress'
|
|
9
|
+
const ownerAddress = '0xOwnerAddress'
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
global.msg = {
|
|
13
|
+
sender: ownerAddress,
|
|
14
|
+
contract: '0xContractAddress',
|
|
15
|
+
staticCall: async (currency, method, args) => {
|
|
16
|
+
// Mock implementation of msg.staticCall
|
|
17
|
+
},
|
|
18
|
+
call: async (currency, method, args) => {
|
|
19
|
+
// Mock implementation of msg.call
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
token = new Leofcoin()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('should create an instance of Leofcoin', () => {
|
|
27
|
+
assert.ok(token instanceof Leofcoin)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('should have correct properties', () => {
|
|
31
|
+
assert.equal(token.name, 'Leofcoin')
|
|
32
|
+
assert.equal(token.symbol, 'LFC')
|
|
33
|
+
assert.equal(token.decimals, 18)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('should grant MINT role to owner', async () => {
|
|
37
|
+
await token.grantRole(ownerAddress, 'MINT')
|
|
38
|
+
assert.equal(await token.hasRole(ownerAddress, 'MINT'), true)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('should be able to mint', async () => {
|
|
42
|
+
await token.grantRole(ownerAddress, 'MINT')
|
|
43
|
+
await token.mint(ownerAddress, 100000n)
|
|
44
|
+
assert.equal(token.balanceOf(ownerAddress), 100000n)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('should be able to transfer', async () => {
|
|
48
|
+
await token.grantRole(ownerAddress, 'MINT')
|
|
49
|
+
await token.mint(receiverAddress, 100000n)
|
|
50
|
+
msg.sender = receiverAddress
|
|
51
|
+
await token.transfer(receiverAddress, otherReceiverAddress, 10000n)
|
|
52
|
+
assert.equal(token.balanceOf(receiverAddress), 90000n)
|
|
53
|
+
assert.equal(token.balanceOf(otherReceiverAddress), 10000n)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('should be able to burn', async () => {
|
|
57
|
+
await token.grantRole(ownerAddress, 'BURN')
|
|
58
|
+
await token.grantRole(ownerAddress, 'MINT')
|
|
59
|
+
await token.mint(ownerAddress, 100000n)
|
|
60
|
+
await token.burn(ownerAddress, 10000n)
|
|
61
|
+
assert.equal(token.balanceOf(ownerAddress), 90000n)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('should not be able to burn more than balance', async () => {
|
|
65
|
+
await token.grantRole(ownerAddress, 'MINT')
|
|
66
|
+
await token.grantRole(ownerAddress, 'BURN')
|
|
67
|
+
await token.mint(ownerAddress, 100000n)
|
|
68
|
+
|
|
69
|
+
await assert.rejects(async () => await token.burn(ownerAddress, 100001n), {
|
|
70
|
+
message: 'amount exceeds balance'
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('should not be able to mint if not MINT role', async () => {
|
|
75
|
+
assert.throws(() => token.mint(ownerAddress, 100000n), { message: 'not allowed' })
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('should not be able to transfer more than balance', async () => {
|
|
79
|
+
await token.grantRole(ownerAddress, 'MINT')
|
|
80
|
+
await token.mint(receiverAddress, 100000n)
|
|
81
|
+
msg.sender = receiverAddress
|
|
82
|
+
assert.throws(() => token.transfer(receiverAddress, otherReceiverAddress, 100001n), {
|
|
83
|
+
message: 'amount exceeds balance'
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
})
|
package/test/validators.js
CHANGED
|
@@ -1,120 +1,119 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
await validators.addValidator(validatorAddress)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
await validators.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
validators.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
validators.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
validatorState
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
})
|
|
1
|
+
import { describe, it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import Validators from '../exports/validators.js'
|
|
4
|
+
|
|
5
|
+
describe('Validators', () => {
|
|
6
|
+
let validators
|
|
7
|
+
let validatorState
|
|
8
|
+
const tokenAddress = '0xTokenAddress'
|
|
9
|
+
const ownerAddress = '0xOwnerAddress'
|
|
10
|
+
const validatorAddress = '0xValidatorAddress'
|
|
11
|
+
const anotherValidatorAddress = '0xAnotherValidatorAddress'
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
global.state = {
|
|
15
|
+
peers: [
|
|
16
|
+
[ownerAddress, { bw: { up: 100, down: 100 } }],
|
|
17
|
+
[validatorAddress, { bw: { up: 100, down: 100 } }],
|
|
18
|
+
[anotherValidatorAddress, { bw: { up: 200, down: 200 } }]
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
global.msg = {
|
|
22
|
+
sender: ownerAddress,
|
|
23
|
+
contract: '0xContractAddress',
|
|
24
|
+
staticCall: async (currency, method, args) => {
|
|
25
|
+
if (method === 'balanceOf') {
|
|
26
|
+
if (args[0] === validatorAddress) return BigInt(100000)
|
|
27
|
+
if (args[0] === anotherValidatorAddress) return BigInt(100000)
|
|
28
|
+
}
|
|
29
|
+
return BigInt(0)
|
|
30
|
+
},
|
|
31
|
+
call: async (currency, method, args) => {
|
|
32
|
+
// Mock implementation of msg.call
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
validators = new Validators(tokenAddress, validatorState)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('should initialize with default values', () => {
|
|
39
|
+
assert.equal(validators.name, 'LeofcoinValidators')
|
|
40
|
+
assert.equal(validators.currency, tokenAddress)
|
|
41
|
+
assert.deepEqual(validators.validators, [ownerAddress])
|
|
42
|
+
assert.equal(validators.totalValidators, 1)
|
|
43
|
+
assert.equal(validators.minimumBalance.toString(), BigInt(50000).toString())
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('should change currency if sender is owner', () => {
|
|
47
|
+
validators.changeCurrency('0xNewCurrencyAddress')
|
|
48
|
+
assert.equal(validators.currency, '0xNewCurrencyAddress')
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('should throw error if non-owner tries to change currency', () => {
|
|
52
|
+
global.msg.sender = validatorAddress
|
|
53
|
+
assert.throws(() => validators.changeCurrency('0xNewCurrencyAddress'), {
|
|
54
|
+
message: 'not an owner'
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('should add a validator if conditions are met', async () => {
|
|
59
|
+
await validators.addValidator(validatorAddress)
|
|
60
|
+
assert.ok(validators.validators.includes(validatorAddress))
|
|
61
|
+
assert.equal(validators.totalValidators, 2)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('should throw error if adding an existing validator', async () => {
|
|
65
|
+
await validators.addValidator(validatorAddress)
|
|
66
|
+
await assert.rejects(async () => await validators.addValidator(validatorAddress), {
|
|
67
|
+
message: 'validator already exists'
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('should throw error if validator balance is too low', async () => {
|
|
72
|
+
global.msg.staticCall = async (currency, method, args) => BigInt(1000)
|
|
73
|
+
await assert.rejects(async () => await validators.addValidator(anotherValidatorAddress), {
|
|
74
|
+
message: 'balance to low! got: 1000 need: 50000'
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('should remove a validator if conditions are met', async () => {
|
|
79
|
+
await validators.addValidator(validatorAddress)
|
|
80
|
+
await validators.removeValidator(validatorAddress)
|
|
81
|
+
assert.ok(!validators.validators.includes(validatorAddress))
|
|
82
|
+
assert.equal(validators.totalValidators, 1)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('should throw error if removing a non-existing validator', async () => {
|
|
86
|
+
await assert.rejects(async () => await validators.removeValidator(validatorAddress), {
|
|
87
|
+
message: 'validator not found'
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('should shuffle validator correctly', async () => {
|
|
92
|
+
validators.shuffleValidator()
|
|
93
|
+
assert.ok(validators.currentValidator.includes(ownerAddress))
|
|
94
|
+
await validators.removeValidator(ownerAddress)
|
|
95
|
+
|
|
96
|
+
global.msg.sender = validatorAddress
|
|
97
|
+
await validators.addValidator(validatorAddress)
|
|
98
|
+
|
|
99
|
+
validators.shuffleValidator()
|
|
100
|
+
assert.ok(validators.currentValidator.includes(validatorAddress))
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('should return the current validator', () => {
|
|
104
|
+
assert.equal(validators.currentValidator, ownerAddress)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('should return state correctly', async () => {
|
|
108
|
+
msg.sender = validatorAddress
|
|
109
|
+
await validators.addValidator(validatorAddress)
|
|
110
|
+
validatorState = validators.state
|
|
111
|
+
assert.deepEqual(validatorState.validators, [ownerAddress, validatorAddress])
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('should restore from state correctly', () => {
|
|
115
|
+
const newValidators = new Validators(tokenAddress, validatorState)
|
|
116
|
+
assert.deepEqual(newValidators.validators, [ownerAddress, validatorAddress])
|
|
117
|
+
assert.equal(newValidators.totalValidators, 2)
|
|
118
|
+
})
|
|
119
|
+
})
|
package/tsconfig.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"module": "NodeNext",
|
|
4
|
-
"declarationDir": "./exports",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"allowJs": true,
|
|
7
|
-
"allowSyntheticDefaultImports": true,
|
|
8
|
-
"resolveJsonModule": true,
|
|
9
|
-
"declaration": true,
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "NodeNext",
|
|
4
|
+
"declarationDir": "./exports",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"allowJs": true,
|
|
7
|
+
"allowSyntheticDefaultImports": true,
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"declaration": true,
|
|
10
|
+
"outDir": "exports",
|
|
11
|
+
"types": ["@leofcoin/types", "@leofcoin/types/global"]
|
|
12
|
+
},
|
|
13
|
+
"include": ["./src/**/*"]
|
|
14
|
+
}
|