@leofcoin/contracts 0.1.21 → 0.1.23
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/package.json +1 -1
- package/src/native-token.ts +16 -1
- package/test/native-token.js +17 -11
package/package.json
CHANGED
package/src/native-token.ts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import Token, { TokenState } from '@leofcoin/standards/token.js'
|
|
2
2
|
|
|
3
|
+
interface LeofcoinState extends TokenState { targetSupply: bigint }
|
|
4
|
+
|
|
3
5
|
export default class Leofcoin extends Token {
|
|
4
|
-
|
|
6
|
+
#targetSupply: bigint
|
|
7
|
+
|
|
8
|
+
constructor(targetSupply: bigint, state: LeofcoinState) {
|
|
5
9
|
super('Leofcoin', 'LFC', 18, state)
|
|
10
|
+
this.#targetSupply = state ? BigInt(state.targetSupply) : BigInt(targetSupply)
|
|
11
|
+
if (this.#targetSupply <= 0n) throw new Error('target supply must be positive')
|
|
12
|
+
// The machine executes protocol fee burns as the immutable contract creator.
|
|
13
|
+
// Persist this capability in fresh genesis state; restored legacy state is
|
|
14
|
+
// intentionally left untouched and cannot activate fee burning.
|
|
15
|
+
if (!state && !this.hasRole(msg.sender, 'BURN')) this.grantRole(msg.sender, 'BURN')
|
|
16
|
+
if (!state && !this.hasRole(msg.sender, 'MINT')) this.grantRole(msg.sender, 'MINT')
|
|
6
17
|
}
|
|
7
18
|
|
|
19
|
+
get targetSupply() { return this.#targetSupply }
|
|
20
|
+
|
|
21
|
+
get state(): LeofcoinState { return { ...super.state, targetSupply: this.#targetSupply } as LeofcoinState }
|
|
22
|
+
|
|
8
23
|
burn(from: address, amount: bigint) {
|
|
9
24
|
// Prevent balance underflow when burning
|
|
10
25
|
if (this.balanceOf(from) < amount) throw new Error('amount exceeds balance')
|
package/test/native-token.js
CHANGED
|
@@ -20,7 +20,7 @@ describe('Leofcoin', () => {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
token = new Leofcoin()
|
|
23
|
+
token = new Leofcoin(1_000_000n)
|
|
24
24
|
})
|
|
25
25
|
|
|
26
26
|
it('should create an instance of Leofcoin', () => {
|
|
@@ -31,21 +31,26 @@ describe('Leofcoin', () => {
|
|
|
31
31
|
assert.equal(token.name, 'Leofcoin')
|
|
32
32
|
assert.equal(token.symbol, 'LFC')
|
|
33
33
|
assert.equal(token.decimals, 18)
|
|
34
|
+
assert.equal(token.targetSupply, 1_000_000n)
|
|
34
35
|
})
|
|
35
36
|
|
|
36
|
-
it('should
|
|
37
|
-
|
|
37
|
+
it('should persist the immutable monetary target in state', () => {
|
|
38
|
+
token.mint(ownerAddress, 100n)
|
|
39
|
+
const restored = new Leofcoin(999n, token.state)
|
|
40
|
+
assert.equal(restored.targetSupply, 1_000_000n)
|
|
41
|
+
assert.equal(restored.totalSupply, 100n)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('should grant protocol MINT role to owner', async () => {
|
|
38
45
|
assert.equal(await token.hasRole(ownerAddress, 'MINT'), true)
|
|
39
46
|
})
|
|
40
47
|
|
|
41
48
|
it('should be able to mint', async () => {
|
|
42
|
-
await token.grantRole(ownerAddress, 'MINT')
|
|
43
49
|
await token.mint(ownerAddress, 100000n)
|
|
44
50
|
assert.equal(token.balanceOf(ownerAddress), 100000n)
|
|
45
51
|
})
|
|
46
52
|
|
|
47
53
|
it('should be able to transfer', async () => {
|
|
48
|
-
await token.grantRole(ownerAddress, 'MINT')
|
|
49
54
|
await token.mint(receiverAddress, 100000n)
|
|
50
55
|
msg.sender = receiverAddress
|
|
51
56
|
await token.transfer(receiverAddress, otherReceiverAddress, 10000n)
|
|
@@ -53,17 +58,18 @@ describe('Leofcoin', () => {
|
|
|
53
58
|
assert.equal(token.balanceOf(otherReceiverAddress), 10000n)
|
|
54
59
|
})
|
|
55
60
|
|
|
56
|
-
it('should
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
it('should grant the genesis owner protocol burn authority', () => {
|
|
62
|
+
assert.equal(token.hasRole(ownerAddress, 'BURN'), true)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('should burn balance and reduce total supply', async () => {
|
|
59
66
|
await token.mint(ownerAddress, 100000n)
|
|
60
67
|
await token.burn(ownerAddress, 10000n)
|
|
61
68
|
assert.equal(token.balanceOf(ownerAddress), 90000n)
|
|
69
|
+
assert.equal(token.totalSupply, 90000n)
|
|
62
70
|
})
|
|
63
71
|
|
|
64
72
|
it('should not be able to burn more than balance', async () => {
|
|
65
|
-
await token.grantRole(ownerAddress, 'MINT')
|
|
66
|
-
await token.grantRole(ownerAddress, 'BURN')
|
|
67
73
|
await token.mint(ownerAddress, 100000n)
|
|
68
74
|
|
|
69
75
|
await assert.rejects(async () => await token.burn(ownerAddress, 100001n), {
|
|
@@ -72,11 +78,11 @@ describe('Leofcoin', () => {
|
|
|
72
78
|
})
|
|
73
79
|
|
|
74
80
|
it('should not be able to mint if not MINT role', async () => {
|
|
81
|
+
msg.sender = receiverAddress
|
|
75
82
|
assert.throws(() => token.mint(ownerAddress, 100000n), { message: 'not allowed' })
|
|
76
83
|
})
|
|
77
84
|
|
|
78
85
|
it('should not be able to transfer more than balance', async () => {
|
|
79
|
-
await token.grantRole(ownerAddress, 'MINT')
|
|
80
86
|
await token.mint(receiverAddress, 100000n)
|
|
81
87
|
msg.sender = receiverAddress
|
|
82
88
|
assert.throws(() => token.transfer(receiverAddress, otherReceiverAddress, 100001n), {
|