-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathNeoBurgerGovernanceToken.cs
More file actions
111 lines (107 loc) · 5.57 KB
/
Copy pathNeoBurgerGovernanceToken.cs
File metadata and controls
111 lines (107 loc) · 5.57 KB
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
using System.Numerics;
using Neo;
using Neo.SmartContract.Framework;
using Neo.SmartContract.Framework.Native;
using Neo.SmartContract.Framework.Services;
using Neo.SmartContract.Framework.Attributes;
using Neo.SmartContract;
namespace NeoBurger
{
[ManifestExtra("Author", "NEOBURGER")]
[ManifestExtra("Email", "developer@neo.org")]
[ManifestExtra("Description", "NeoBurger Governance Token")]
[SupportedStandards("NEP-17")]
[ContractPermission("*", "*")]
public class NeoBurgerGovernanceToken : Nep17Token
{
private const byte PREFIX_TEE = 0x01;
private const byte PREFIX_EXECUTION = 0x02;
private const byte PREFIX_EXECUTED = 0x03;
private const byte PREFIX_PAUSEUNTIL = 0x04;
private const byte PREFIX_MINTROOT = 0x05;
private const byte PREFIX_MINTED = 0x06;
[InitialValue("[TODO]: ARGS", ContractParameterType.Hash160)]
private static readonly UInt160 DEFAULT_TEE = default;
private const uint DEFAULT_WAITTIME = 86400000 * 4;
public override byte Decimals() => 10;
public override string Symbol() => "NOBUG";
public static UInt160 TEE() => (UInt160)Storage.Get(Storage.CurrentContext, new byte[] { PREFIX_TEE });
public static bool NotPaused() => (BigInteger)Storage.Get(Storage.CurrentContext, new byte[] { PREFIX_PAUSEUNTIL }) < Runtime.Time;
public static UInt256 MintRoot() => (UInt256)Storage.Get(Storage.CurrentContext, new byte[] { PREFIX_MINTROOT });
public static void _deploy(object data, bool update)
{
Storage.Put(Storage.CurrentContext, new byte[] { PREFIX_TEE }, DEFAULT_TEE);
}
public static void SubmitApprovedExecution(UInt256 digest)
{
ExecutionEngine.Assert(Runtime.CheckWitness(TEE()) && NotPaused());
new StorageMap(Storage.CurrentContext, PREFIX_EXECUTION).Put(digest, Runtime.Time + DEFAULT_WAITTIME);
}
public static void SubmitExecution(UInt160 caller, UInt256 digest)
{
ExecutionEngine.Assert(Runtime.CheckWitness(caller) && BalanceOf(caller) * 2 > TotalSupply());
new StorageMap(Storage.CurrentContext, PREFIX_EXECUTION).Put(digest, Runtime.Time + DEFAULT_WAITTIME / 2);
}
public static void BanExecution(UInt160 caller, UInt256 digest)
{
ExecutionEngine.Assert(Runtime.CheckWitness(caller) && BalanceOf(caller) * 2 > TotalSupply());
new StorageMap(Storage.CurrentContext, PREFIX_EXECUTED).Put(digest, -1);
}
public static object Execute(UInt160 scripthash, string method, object[] args, BigInteger nonce)
{
ExecutionEngine.Assert(NotPaused());
ByteString digest = CryptoLib.Sha256(StdLib.Serialize(new object[] { scripthash, method, args, nonce }));
BigInteger timestamp = (BigInteger)new StorageMap(Storage.CurrentContext, PREFIX_EXECUTION).Get(digest);
ExecutionEngine.Assert(timestamp > 0);
BigInteger now = Runtime.Time;
ExecutionEngine.Assert(timestamp < now);
StorageMap executed = new(Storage.CurrentContext, PREFIX_EXECUTED);
ExecutionEngine.Assert((BigInteger)executed.Get(digest) == 0);
executed.Put(digest, now);
return Contract.Call(scripthash, method, CallFlags.All, args);
}
public static void Claim(UInt160 claimer, BigInteger num, BigInteger nonce, UInt256[] proof)
{
const byte LEAF = 0x00;
const byte INTERNAL = 0x01;
UInt256 userDigest = (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { LEAF, claimer, num, nonce }));
StorageMap minted = new(Storage.CurrentContext, PREFIX_MINTED);
ExecutionEngine.Assert((BigInteger)minted.Get(userDigest) == 0);
UInt256 digest = userDigest;
foreach (UInt256 sibling in proof)
{
if ((BigInteger)digest < (BigInteger)sibling)
digest = (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { INTERNAL, digest, sibling }));
else
digest = (UInt256)CryptoLib.Sha256(StdLib.Serialize(new object[] { INTERNAL, sibling, digest }));
}
ExecutionEngine.Assert(digest == Storage.Get(Storage.CurrentContext, new byte[] { PREFIX_MINTROOT }));
minted.Put(userDigest, num);
Mint(claimer, num);
ExecutionEngine.Assert(TotalSupply() < BigInteger.Pow(2, 64));
}
public static void OnNEP17Payment(UInt160 from, BigInteger amount, object data)
{
}
public static void SetTEE(UInt160 newTEE)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Runtime.ExecutingScriptHash));
Storage.Put(Storage.CurrentContext, new byte[] { PREFIX_TEE }, newTEE);
}
public static void SetMintRoot(UInt256 root)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Runtime.ExecutingScriptHash));
Storage.Put(Storage.CurrentContext, new byte[] { PREFIX_MINTROOT }, root);
}
public static void PauseDAO(UInt160 caller)
{
ExecutionEngine.Assert(Runtime.CheckWitness(caller) && BalanceOf(caller) > TotalSupply() / 4);
Storage.Put(Storage.CurrentContext, new byte[] { PREFIX_PAUSEUNTIL }, Runtime.Time + DEFAULT_WAITTIME);
}
public static void Update(ByteString nefFile, string manifest)
{
ExecutionEngine.Assert(Runtime.CheckWitness(Runtime.ExecutingScriptHash));
ContractManagement.Update(nefFile, manifest, null);
}
}
}