-
Notifications
You must be signed in to change notification settings - Fork 4
/
BurgerNEO.cs
169 lines (161 loc) · 7.77 KB
/
BurgerNEO.cs
1
2
3
4
5
6
7
8
9
10
11
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
using System;
using System.ComponentModel;
using System.Numerics;
using Neo;
using Neo.SmartContract;
using Neo.SmartContract.Framework;
using Neo.SmartContract.Framework.Native;
using Neo.SmartContract.Framework.Services;
using Neo.SmartContract.Framework.Attributes;
using Neo.Cryptography.ECC;
namespace NeoBurger
{
[ManifestExtra("Author", "NEOBURGER")]
[ManifestExtra("Email", "developer@neo.org")]
[ManifestExtra("Description", "NeoBurger Core Contract")]
[SupportedStandards("NEP-17")]
[ContractPermission("*", "*")]
public class BurgerNEO : Nep17Token
{
private const byte PREFIXOWNER = 0x01;
private const byte PREFIXAGENT = 0x02;
private const byte PREFIXSTRATEGIST = 0x03;
private const byte PREFIXREWARDPERTOKENSTORED = 0x04;
private const byte PREFIXREWARD = 0x05;
private const byte PREFIXPAID = 0x06;
private const byte PREFIXCANDIDATEWHITELIST = 0x07;
private static readonly BigInteger DEFAULTCLAIMREMAIN = 99000000;
private static readonly BigInteger DEFAULTWITHDRAWFACTOR = 1000;
public override byte Decimals() => 8;
public override string Symbol() => "bNEO";
public static UInt160 Owner() => (UInt160)Storage.Get(Storage.CurrentContext, new byte[] { PREFIXOWNER });
public static UInt160 Agent(BigInteger i) => (UInt160)new StorageMap(Storage.CurrentContext, PREFIXAGENT).Get((ByteString)i);
public static UInt160 Strategist() => (UInt160)Storage.Get(Storage.CurrentContext, new byte[] { PREFIXSTRATEGIST });
public static ByteString Candidate(ECPoint target) => new StorageMap(Storage.CurrentContext, PREFIXCANDIDATEWHITELIST).Get(target);
public static BigInteger Reward(UInt160 account) => SyncAccount(account) ? (BigInteger)new StorageMap(Storage.CurrentContext, PREFIXREWARD).Get(account) : 0;
public static BigInteger RPS() => (BigInteger)Storage.Get(Storage.CurrentContext, new byte[] { PREFIXREWARDPERTOKENSTORED });
public static void OnNEP17Payment(UInt160 from, BigInteger amount, object data)
{
if (Runtime.CallingScriptHash == GAS.Hash && amount > 0)
{
BigInteger ts = TotalSupply();
if (ts > 0)
{
BigInteger rps = (BigInteger)Storage.Get(Storage.CurrentContext, new byte[] { PREFIXREWARDPERTOKENSTORED });
Storage.Put(Storage.CurrentContext, new byte[] { PREFIXREWARDPERTOKENSTORED }, amount * DEFAULTCLAIMREMAIN / ts + rps);
}
}
SyncAccount(from);
if (Runtime.CallingScriptHash == NEO.Hash)
{
ExecutionEngine.Assert(NEO.Transfer(Runtime.ExecutingScriptHash, Agent(0), NEO.BalanceOf(Runtime.ExecutingScriptHash)));
Mint(from, amount * 100000000);
}
else if (Runtime.CallingScriptHash == GAS.Hash && amount > 0 && data is null)
{
amount *= DEFAULTWITHDRAWFACTOR;
Burn(from, amount);
amount /= 100000000;
for (BigInteger i = 0; amount > 0; i++)
{
UInt160 agent = Agent(i);
BigInteger balance = NEO.BalanceOf(agent) - 1;
if (amount > balance)
{
amount -= balance;
Contract.Call(agent, "transfer", CallFlags.All, new object[] { from, balance });
}
else
{
Contract.Call(agent, "transfer", CallFlags.All, new object[] { from, amount });
break;
}
}
}
else if (Runtime.CallingScriptHash == Runtime.ExecutingScriptHash)
{
BigInteger reward = (BigInteger)new StorageMap(Storage.CurrentContext, PREFIXREWARD).Get(from);
if (reward > 0)
{
new StorageMap(Storage.CurrentContext, PREFIXREWARD).Put(from, 0);
ExecutionEngine.Assert(GAS.Transfer(Runtime.ExecutingScriptHash, from, reward));
}
if (amount > 0)
{
ExecutionEngine.Assert(Nep17Token.Transfer(Runtime.ExecutingScriptHash, from, amount, null));
}
}
}
public static new bool Transfer(UInt160 from, UInt160 to, BigInteger amount, object data)
{
if (amount > 0)
{
SyncAccount(from);
SyncAccount(to);
}
return Nep17Token.Transfer(from, to, amount, data);
}
public static bool SyncAccount(UInt160 account)
{
BigInteger rps = (BigInteger)Storage.Get(Storage.CurrentContext, new byte[] { PREFIXREWARDPERTOKENSTORED });
BigInteger balance = BalanceOf(account);
if (balance > 0)
{
BigInteger reward = (BigInteger)new StorageMap(Storage.CurrentContext, PREFIXREWARD).Get(account);
BigInteger paid = (BigInteger)new StorageMap(Storage.CurrentContext, PREFIXPAID).Get(account);
BigInteger earned = balance * (rps - paid) / 100000000 + reward;
new StorageMap(Storage.CurrentContext, PREFIXREWARD).Put(account, earned);
}
new StorageMap(Storage.CurrentContext, PREFIXPAID).Put(account, rps);
return true;
}
public static void TrigVote(BigInteger i, ECPoint target)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Strategist()));
ExecutionEngine.Assert(new StorageMap(Storage.CurrentContext, PREFIXCANDIDATEWHITELIST).Get(target) is not null);
Contract.Call(Agent(i), "vote", CallFlags.All, new object[] { target });
}
public static void TrigTransfer(BigInteger i, BigInteger j, BigInteger amount)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Strategist()));
Contract.Call(Agent(i), "transfer", CallFlags.All, new object[] { Agent(j), amount });
}
public static void SetOwner(UInt160 owner)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Owner()));
Storage.Put(Storage.CurrentContext, new byte[] { PREFIXOWNER }, owner);
}
public static void SetAgent(BigInteger i, UInt160 agent)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Owner()));
new StorageMap(Storage.CurrentContext, PREFIXAGENT).Put((ByteString)i, agent);
}
public static void SetStrategist(UInt160 strategist)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Owner()));
Storage.Put(Storage.CurrentContext, new byte[] { PREFIXSTRATEGIST }, strategist);
}
public static void AllowCandidate(ECPoint target)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Owner()));
StorageMap candidates = new StorageMap(Storage.CurrentContext, PREFIXCANDIDATEWHITELIST);
candidates.Put(target, 1);
}
public static void DisallowCandidate(ECPoint target)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Owner()));
StorageMap candidates = new StorageMap(Storage.CurrentContext, PREFIXCANDIDATEWHITELIST);
candidates.Delete(target);
}
public static void Update(ByteString nefFile, string manifest)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Owner()));
ContractManagement.Update(nefFile, manifest, null);
}
public static void Pika(BigInteger amount)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Owner()));
ExecutionEngine.Assert(GAS.Transfer(Runtime.ExecutingScriptHash, Owner(), amount));
}
}
}