#include "elrond/context.h"
#include "elrond/bigInt.h"
byte sender[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte recipient[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte caller[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte currentKey[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte approveEvent[32] = {0x71,0x34,0x69,0x2B,0x23,0x0B,0x9E,0x1F,0xFA,0x39,0x09,0x89,0x04,0x72,0x21,0x34,0x15,0x96,0x52,0xB0,0x9C,0x5B,0xC4,0x1D,0x88,0xD6,0x69,0x87,0x79,0xD2,0x28,0xFF};
byte transferEvent[32] = {0xF0,0x99,0xCD,0x8B,0xDE,0x55,0x78,0x14,0x84,0x2A,0x31,0x21,0xE8,0xDD,0xFD,0x43,0x3A,0x53,0x9B,0x8C,0x9F,0x14,0xBF,0x31,0xEB,0xF1,0x08,0xD1,0x2E,0x61,0x96,0xE9};
byte currentTopics[96] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte currentLogVal[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void computeTotalSupplyKey(byte *destination) {
for (int i = 0; i < 32; i++) {
destination[i] = 0;
}
}
void computeBalanceKey(byte *destination, byte *address) {
destination[0] = 1;
destination[1] = 0;
for (int i = 0; i < 30; i++) {
destination[2+i] = address[i];
}
}
void computeAllowanceKey(byte *destination, byte *from, byte* to) {
destination[0] = 2;
for (int i = 0; i < 15; i++) {
destination[1+i] = from[10+i];
}
for (int i = 0; i < 16; i++) {
destination[16+i] = to[10+i];
}
}
void saveLogWith3Topics(byte *topic1, byte *topic2, byte *topic3, bigInt value) {
for (int i = 0; i < 32; i++) {
currentTopics[i] = topic1[i];
}
for (int i = 0; i < 32; i++) {
currentTopics[32+i] = topic2[i];
}
for (int i = 0; i < 32; i++) {
currentTopics[64+i] = topic3[i];
}
int valueLen = bigIntGetBytes(value, currentLogVal);
writeLog(currentLogVal, valueLen, currentTopics, 3);
}
void init() {
if (getNumArguments() != 1) {
signalError();
return;
}
getCaller(sender);
bigInt totalSupply = bigIntNew(0);
bigIntGetSignedArgument(0, totalSupply);
computeTotalSupplyKey(currentKey);
bigIntStorageStore(currentKey, totalSupply);
computeBalanceKey(currentKey, sender);
bigIntStorageStore(currentKey, totalSupply);
}
void totalSupply() {
if (getNumArguments() != 0) {
signalError();
return;
}
computeTotalSupplyKey(currentKey);
bigInt totalSupply = bigIntNew(0);
bigIntStorageLoad(currentKey, totalSupply);
bigIntFinish(totalSupply);
}
void balanceOf() {
if (getNumArguments() != 1) {
signalError();
return;
}
getArgument(0, caller);
computeBalanceKey(currentKey, caller);
bigInt balance = bigIntNew(0);
bigIntStorageLoad(currentKey, balance);
bigIntFinish(balance);
}
void allowance() {
if (getNumArguments() != 2) {
signalError();
return;
}
getArgument(0, sender);
getArgument(1, recipient);
computeAllowanceKey(currentKey, sender, recipient);
bigInt allowance = bigIntNew(0);
bigIntStorageLoad(currentKey, allowance);
bigIntFinish(allowance);
}
void transferToken() {
if (getNumArguments() != 2) {
signalError();
return;
}
getCaller(sender);
getArgument(0, recipient);
bigInt amount = bigIntNew(0);
bigIntGetSignedArgument(1, amount);
if (bigIntCmp(amount, bigIntNew(0)) < 0) {
signalError();
return;
}
computeBalanceKey(currentKey, sender);
bigInt senderBalance = bigIntNew(0);
bigIntStorageLoad(currentKey, senderBalance);
if (bigIntCmp(amount, senderBalance) > 0) {
signalError();
return;
}
bigIntSub(senderBalance, senderBalance, amount);
bigIntStorageStore(currentKey, senderBalance);
computeBalanceKey(currentKey, recipient);
bigInt receiverBalance = bigIntNew(0);
bigIntStorageLoad(currentKey, receiverBalance);
bigIntAdd(receiverBalance, receiverBalance, amount);
bigIntStorageStore(currentKey, receiverBalance);
saveLogWith3Topics(transferEvent, sender, recipient, amount);
int64finish(1);
}
void approve() {
if (getNumArguments() != 2) {
signalError();
return;
}
getCaller(sender);
getArgument(0, recipient);
bigInt amount = bigIntNew(0);
bigIntGetSignedArgument(1, amount);
if (bigIntCmp(amount, bigIntNew(0)) < 0) {
signalError();
return;
}
computeAllowanceKey(currentKey, sender, recipient);
bigIntStorageStore(currentKey, amount);
saveLogWith3Topics(approveEvent, sender, recipient, amount);
int64finish(1);
}
void transferFrom() {
if (getNumArguments() != 3) {
signalError();
return;
}
getCaller(caller);
getArgument(0, sender);
getArgument(1, recipient);
bigInt amount = bigIntNew(0);
bigIntGetSignedArgument(2, amount);
if (bigIntCmp(amount, bigIntNew(0)) < 0) {
signalError();
return;
}
computeAllowanceKey(currentKey, sender, caller);
bigInt allowance = bigIntNew(0);
bigIntStorageLoad(currentKey, allowance);
if (bigIntCmp(amount, allowance) > 0) {
signalError();
return;
}
bigIntSub(allowance, allowance, amount);
bigIntStorageStore(currentKey, allowance);
computeBalanceKey(currentKey, sender);
bigInt senderBalance = bigIntNew(0);
bigIntStorageLoad(currentKey, senderBalance);
if (bigIntCmp(amount, senderBalance) > 0) {
signalError();
return;
}
bigIntSub(senderBalance, senderBalance, amount);
bigIntStorageStore(currentKey, senderBalance);
computeBalanceKey(currentKey, recipient);
bigInt receiverBalance = bigIntNew(0);
bigIntStorageLoad(currentKey, receiverBalance);
bigIntAdd(receiverBalance, receiverBalance, amount);
bigIntStorageStore(currentKey, receiverBalance);
saveLogWith3Topics(transferEvent, sender, recipient, amount);
int64finish(1);
}
i32 selector[1] = {0};
void _main(void) {
}