Bootstrap Bootstrap
            {
   0x0000000000000000000000000000000000000000: {
      address: "0x0000000000000000000000000000000000000000",
      balance: "0",
      ens: "Null Address",
      "transactions": [],
      code: null,
      codeHash: null,
      "codeAbi": [],
      contractName: null,
      "storage": {},
      storageHash: null,
      savedOnBlockNumber: "0"
   },
   0x0000000000000000000000000000000000000001: {
      address: "0x0000000000000000000000000000000000000001",
      balance: "-14500000000000000000000",
      ens: "Mint Address",
      "transactions": [],
      code: null,
      codeHash: null,
      "codeAbi": [],
      contractName: null,
      "storage": {},
      storageHash: "0xb48d38f93eaa084033fc5970bf96e559c33c4cdc07d889ab00b4d63f9590739d",
      savedOnBlockNumber: "49"
   },
   0x0000000000000000000000000000000000000002: {
      address: "0x0000000000000000000000000000000000000002",
      balance: "0",
      ens: "Burn Address",
      "transactions": [],
      code: null,
      codeHash: null,
      "codeAbi": [],
      contractName: null,
      "storage": {},
      storageHash: null,
      savedOnBlockNumber: "0"
   },
   0xccf8ba457dcad7ee6a0361c96846a0f79744b113: {
      address: "0xccf8ba457dcad7ee6a0361c96846a0f79744b113",
      balance: "14250000506402000000000",
      transactions: [
         "0x769cdbd9cf5e7f437df3a7f1b8020b66933d562fcec2b04982a6db364b7e4368",
         "0xc26da3a9c97df9c900dad01068900bbc283f53e191e45aa27e753452f5de4513",
         "0x30cba6a6848c69fe29d79a6eb059accf512d6021704f3b40f9108382a0f20090",
         "0xb32a63ebe1e1c60d471eeeedae9c86a0ff211736e7ccb84078c51da86d0dd2d8",
         "0x194cae77eda01be54da0d49a51846deb0b138797565b73b012900c782acd2daa",
         "0xf5ff4d07877270f43c650fc44c0b7f3746af8bc96b81c331232a8e546eddd118",
         "0x3f7a6a28c7cf9385da34dc150f359bbc079ac93b8730f3decfcaedd997097d87",
         "0x60334c2fbb9a0da329f6503562b6d3abb0f589f735490b6cb548804d357d9f32",
         "0x9fc68f8ad63e0e9e9d5804188cdb37ca0b390ace7e15679419c874049f93092c"
      ],
      code: null,
      codeHash: null,
      "codeAbi": [],
      contractName: null,
      "storage": {},
      storageHash: "0xb48d38f93eaa084033fc5970bf96e559c33c4cdc07d889ab00b4d63f9590739d",
      savedOnBlockNumber: "49"
   },
   0x131a190fa22cb867abf58193bf9e7640e9fce682: {
      address: "0x131a190fa22cb867abf58193bf9e7640e9fce682",
      balance: "999999506663000000000",
      transactions: [
         "0x1964b5ae0f32659b2cc50f7aa8e2f2d7cb213197adb64008206f1b32ba49aa2f",
         "0x5f688782a2de8e88327e6930d4133fd833252e1255a7595d619964a2f58bba67",
         "0x242f750a46ec75c386606f20ed7d4c2a1486cf0150919aef761010e89c5b43eb",
         "0x484d9c454cc34fc752903e492ce5c573118ba68824594a6fe0eabedd938361f6",
         "0x86764232071da39aafa015bef38b5a40f390b01afa54744d0e3965cca608b472",
         "0x2d9987bffd02b12a95167d157f4d345b1954b62f043e308b892e916e0b217308",
         "0xcef76138cfb3883fae36032061551ff0dcff8785795478380912e44318fe40bd",
         "0xfe576f241ed53b32a1748eb53e93838c2e60c2ffc866a993482590a854d9152e",
         "0xd242c8ffbe99682086ac93dfbdb2f83ce794ef8af244cc33bf59368aaf85b603",
         "0x15a7d8bf0c3ef7b0d877bd57e0410f1d73fe4bc4e3425a606f3dab8b44370584",
         "0xd35ada50d67fe104087551ffcc9b05db08902ced472e9d26982fce6f59b66cf1",
         "0x2294b753e054ffa64adcafc660939c2f9d40009cde3175a78eb57c6985399b65",
         "0xb3abc261f15cb3e4270615cc4c5f5a9bfab9ffbf6772c6361092d95732329b13",
         "0x08838c57c86c750b35a3c2318e39f2d9685225d4080c2c38d24b7ef5add02d9b",
         "0xe51decb9e38a2bb8630f947fcd3e45e61bcdeae36f8e92130c7f06d8d344ed9a",
         "0xf5a2934425fc3114cd64b383f3adfd9813f0c1b4bb2147a9bc37cb6bd6a72b2a",
         "0xe04941629d6246a16a45de1a024aaf9cc18110ef6c2e1dc4f38cbea4a81c2dd2",
         "0x121ccb7eaf7a50218653db6da441ce98ba31ac8ea2a56211ad512f786723d799",
         "0x6c731343fb71c49d30ba2ad776743a3ac994b55559f1a7cacb6d2edacc876b43",
         "0x270780dd570baa0939e878e62eff1a299b708a6a2a376cce05110c1efdc4dd7d",
         "0xf0862f9fa47e615ca5f7afd8ab3e70c109f5b7f9f86f2d686a919464a4f2149c",
         "0x67a182fd9147cc9a2160566428468b52b8880b7900f745d03074438fdbf953af",
         "0x64c30834336d117661c16a25ab6e47b2819a8518e3df66ac4c4e3b4b4974e42a",
         "0x2c32e99703210bdadc2bba260f770e7e8c790690c2149c9ce0255d3bc55cf0fe",
         "0x43d2e7922f2608ad4c091c265f857962698c79c4aa6385793ec39034004579ee",
         "0x83b887180a7347a09434575e16a0d50565c8b884367a1ca154b7e9325c0934ed",
         "0x8bd2e15463e7077c51933818c91b92287dc272f79db15ebd48cf6dc84ea0bae2",
         "0x08792b452d315a340f7f4ee093822b61c4386c80706e8e2c71d80ba12c9bdd9f",
         "0x72362ea00b8ea3be471e03529de92cc594e89e21ff907040dcb578d311c329ce",
         "0x5e413a2d19b593f8455e747d09b69e38a44712f9166cfe282bdbbdb5a0098e92",
         "0xc4d96a5b29be167f24d2d28ee4dc3791e81eb839a0ba92ab99d1392b595ed541",
         "0x9875bfede4e11ecf7234698a14ed497864c10f9ba1baf77b045fbca420c1bb00",
         "0x21a481eab803eba639e6dfae09491919c5cc637ae0d97c63a3c557a7fa316ded",
         "0x63a85145c4535cd1cb3b86206215a855e6d3102d03e87608e04019a635b84e96",
         "0x515a83ca0d5a12c7f1875c48446d1f1d8eb82a42781c153072d29be86fee41d0",
         "0x7c5e6c6cc0e0dcd1f9762f541913543cd006d5c3f97cba2d97f53959819053f4",
         "0xded491ff92f07cb14728354689cb16b1e5f3bb9b338776c1e96dd6bff9215e51",
         "0xacbccaadfc4e8ee297241ee3d53c50b6cca88acf446cf73223560b70b794669f",
         "0xdf8a85a40ae16d2ff22ae153a108e9c89cdc54bfb5ae0d9623a5540bc160b1e0",
         "0x433de861a571f823a73baf3c8f0e2ed8b26d3b36df57a9206b958e8788ff3c54",
         "0x333540a1c860d3a4a7293a1379658d2e98fa7fc7c20308db62c8b42dfe851334",
         "0x56aa930a78d7b4dd3ddeea9b692e825100fd4a5076b82131f79d7f8bbf4a990e",
         "0x0d1568e67db0f458336483f6fb6be4e6085dc07c94390d1614d06132bbbfb381",
         "0xb1dfea4931e97dcbc74d04df5fcb99565afc904719197134ddb07843f1932998",
         "0x79bdb61267021b32912944437760757c5a31e92b30a9142222bce04bd8a00fbc",
         "0x9f70ab2b8b65c8c2ee0fbe6544a649a594b7e290cf8bf58f5ac5d992283bca5e",
         "0x021f05bed67059020def15d6a018bce0a11ef03cb428f47cb6966b9e7e87af87",
         "0x8c10f2618c30e1eff594ee0cb80605fa9dc9b701b124c2e670db08add42ef965"
      ],
      code: null,
      codeHash: null,
      "codeAbi": [],
      contractName: null,
      "storage": {},
      storageHash: "0xb48d38f93eaa084033fc5970bf96e559c33c4cdc07d889ab00b4d63f9590739d",
      savedOnBlockNumber: "49"
   },
   0x2347d36cf0d94b98bab6d6d41c6f94d7214830ad: {
      address: "0x2347d36cf0d94b98bab6d6d41c6f94d7214830ad",
      balance: "0",
      "transactions": [],
      code: "/*
Name: Wrapped BNB => Wrapped KARMA
Version: 0.0.3
Source:
- WBNB: https://github.com/pancakeswap/pancake-farm/blob/master/contracts/libs/WBNB.sol
Deploy: https://bscscan.com/address/0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
*/


class Ownable {
owner = '0x0000000000000000000000000000000000000000';

OwnershipTransferred(oldOwner, newOwner) {} // event


constructor() {
this.owner = msg.sender;
}

getOwner() {
return [this.owner];
}

transferOwnership(newOwner) {
require(newOwner != address(0), "Ownable: new owner is the zero address");
this._transferOwnership(newOwner);
}

_transferOwnership(newOwner) {
newOwner = newOwner.toLowerCase();
const oldOwner = this.owner;
this.owner = newOwner;
emit('OwnershipTransferred', [oldOwner, newOwner]);
}

_onlyOwner(next) {
require(msg.sender.toLowerCase() == this.owner, 'only owner can execute this');
next();
}
}

// Methods
Ownable.prototype.OwnershipTransferred.event = true;
Ownable.prototype.OwnershipTransferred.inputs = ['address indexed', 'address indexed'];

// Methods
Ownable.prototype.getOwner.view = true;
Ownable.prototype.getOwner.outputs = ['address'];

Ownable.prototype.transferOwnership.inputs = ['address'];
Ownable.prototype.transferOwnership.modifiers = ['_onlyOwner'];

Ownable.prototype._transferOwnership.internal = true;

Ownable.prototype._onlyOwner.internal = true;




class ERC20Token extends Ownable {
name = 'ERC20 Token';
symbol = 'ERC20';
decimals = 18;
totalSupply = number('0');

allowed = {};
balances = {};

supportedInterfaces = {
'0x36372b07': true, // ERC20
'0x06fdde03': true, // ERC20 name
'0x95d89b41': true, // ERC20 symbol
'0x313ce567': true, // ERC20 decimals
};


Transfer(sender, recipient, amount) {} // event
Approval(owner, spender, amount) {} // event
Mint(minter, amount) {} // event
Burn(burner, amount) {} // event


balanceOf(holderAddress) {
holderAddress = holderAddress.toLowerCase();
var tokenBalances = this.balances || {};

if (holderAddress in tokenBalances) {
const balance = tokenBalances[holderAddress];
return [balance];
}
return [number(0)];
}

transfer(recipient, amount) {
recipient = recipient.toLowerCase();
const sender = msg.sender;
var tokenBalances = this.balances || {};

if (! (sender in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}

emit('Transfer', [sender, recipient, amount]);
return [true];
}


transferFrom(sender, recipient, amount) {
sender = sender.toLowerCase();
recipient = recipient.toLowerCase();

var tokenBalances = this.balances || {};
var tokenAllowances = this.allowed || {};

require(sender in tokenBalances, 'MISSING_TOKEN_BALANCE');
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

require(sender == msg.sender || (sender in tokenAllowances && msg.sender in tokenAllowances[sender]), "MISSING_ALLOWANCE");
if (sender != msg.sender && tokenAllowances[sender][msg.sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_ALLOWANCE');
}

tokenAllowances[sender][msg.sender] = tokenAllowances[sender][msg.sender].sub(amount);

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}


emit('Transfer', [sender, recipient, amount]);
return [true];
}


allowance(owner, spender) {
owner = owner.toLowerCase();
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (owner in tokenAllowances && spender in tokenAllowances[owner]) {
return [tokenAllowances[owner][spender]];
}
return [number(0)];
}

approve(spender, value) {
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (! (msg.sender in tokenAllowances)) {
tokenAllowances[msg.sender] = {};
}
tokenAllowances[msg.sender][spender] = value;
emit('Approval', [msg.sender, spender, value]);
return [true];
}


mint(userAddress, amount) {
this._mint(userAddress, amount);
}

_mint(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: mint to the zero address');
}

if (this._incrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.add(amount);
}

emit('Mint', [userAddress, amount]);
}


burn(userAddress, amount) {
this._burn(userAddress, amount);
}

_burn(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: burn from the zero address');
}

if (this._decrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.sub(amount);
}

emit('Burn', [userAddress, amount]);
}


supportsInterface(interfaceID) {
const _interfaces = this.supportedInterfaces || {};
return [
((interfaceID in _interfaces)
? _interfaces[interfaceID]
: false)
];
}


_decrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (amount.gt(tokenBalances[holderAddress])) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].sub(amount);
return true;
}


_incrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
tokenBalances[holderAddress] = number(0);
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].add(amount);
return true;
}

}

// Events
ERC20Token.prototype.Transfer.event = true;
ERC20Token.prototype.Transfer.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Approval.event = true;
ERC20Token.prototype.Approval.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Mint.event = true;
ERC20Token.prototype.Mint.inputs = ['address indexed', 'uint256'];

ERC20Token.prototype.Burn.event = true;
ERC20Token.prototype.Burn.inputs = ['address indexed', 'uint256'];

// Methods
ERC20Token.prototype.balanceOf.view = true;
ERC20Token.prototype.balanceOf.inputs = ['address'];
ERC20Token.prototype.balanceOf.outputs = ['uint256'];

ERC20Token.prototype.transfer.inputs = ['address', 'uint256'];
ERC20Token.prototype.transfer.outputs = ['bool'];

ERC20Token.prototype.transferFrom.inputs = ['address', 'address', 'uint256'];
ERC20Token.prototype.transferFrom.outputs = ['bool'];

ERC20Token.prototype.allowance.view = true;
ERC20Token.prototype.allowance.inputs = ['address', 'address'];
ERC20Token.prototype.allowance.outputs = ['uint256'];

ERC20Token.prototype.approve.inputs = ['address', 'uint256'];
ERC20Token.prototype.approve.outputs = ['bool'];

ERC20Token.prototype.mint.inputs = ['address', 'uint256'];
ERC20Token.prototype.mint.modifiers = ['_onlyOwner'];

ERC20Token.prototype._mint.internal = true;

ERC20Token.prototype.burn.inputs = ['address', 'uint256'];
ERC20Token.prototype.burn.modifiers = ['_onlyOwner'];

ERC20Token.prototype._burn.internal = true;

ERC20Token.prototype.supportsInterface.view = true;
ERC20Token.prototype.supportsInterface.inputs = ['bytes4'];
ERC20Token.prototype.supportsInterface.outputs = ['bool'];

ERC20Token.prototype._decrementUserBalance.internal = true;

ERC20Token.prototype._incrementUserBalance.internal = true;






class WKARMA extends ERC20Token {
name = 'Wrapped KARMA';
symbol = 'WKARMA';


deposit() {
if (! (msg.sender in this.balances)) {
this.balances[msg.sender] = number(0);
}

this.balances[msg.sender] = this.balances[msg.sender].add(msg.value);
this.totalSupply = this.totalSupply.add(msg.value);

require(this.totalSupply.eq(address(this).balance), 'TOTAL_SUPPLY_MISMATCH');
this.drain();
emit('Deposit', [msg.sender, msg.value]);
}


Deposit(sender, value) {} // event


withdraw(wad) {
require(msg.sender in this.balances && ! this.balances[msg.sender].lt(wad));
this.drain();

this.balances[msg.sender] = this.balances[msg.sender].sub(wad);
this.totalSupply = this.totalSupply.sub(wad);

address(msg.sender).transfer(wad);

require(this.totalSupply.eq(address(this).balance), 'TOTAL_SUPPLY_MISMATCH');
emit('Withdrawal', [msg.sender, wad]);
}


Withdrawal(sender, value) {} // event


drain() {
if (address(this).balance.gt(this.totalSupply)) {
const overBalance = address(this).balance.sub(this.totalSupply);
address(this.owner).transfer(overBalance);
emit('Drain', [msg.sender, overBalance]);
}
}


Drain(sender, value) {} // event

}


// Events
WKARMA.prototype.Deposit.event = true;
WKARMA.prototype.Deposit.inputs = ['address indexed', 'uint256'];

WKARMA.prototype.Withdrawal.event = true;
WKARMA.prototype.Withdrawal.inputs = ['address indexed', 'uint256'];

WKARMA.prototype.Drain.event = true;
WKARMA.prototype.Drain.inputs = ['address indexed', 'uint256'];

// Methods
WKARMA.prototype.deposit.payable = true;

WKARMA.prototype.withdraw.inputs = ['uint256'];


return WKARMA;
"
, codeHash: "0xb509231997a77b225178905db5d62a4a30c04d52130f2e59ce5b4206d6189d81", codeAbi: { 0x8da5cb5b: { constant: true, "inputs": [], name: "owner", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0x06fdde03: { constant: true, "inputs": [], name: "name", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x95d89b41: { constant: true, "inputs": [], name: "symbol", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x313ce567: { constant: true, "inputs": [], name: "decimals", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x18160ddd: { constant: true, "inputs": [], name: "totalSupply", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x19e1fca4: { constant: true, "inputs": [], name: "allowed", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x7bb98a68: { constant: true, "inputs": [], name: "balances", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x037cc0e6: { constant: true, "inputs": [], name: "supportedInterfaces", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xd0e30db0: { "inputs": [], name: "deposit", "outputs": [], stateMutability: "payable", type: "function" }, 0xe1fffcc4: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "value", type: "uint256", indexed: false } ], name: "Deposit", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x2e1a7d4d: { inputs: [ { name: "wad", type: "uint256" } ], name: "withdraw", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x7fcf532c: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "value", type: "uint256", indexed: false } ], name: "Withdrawal", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x9890220b: { "inputs": [], name: "drain", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0xf36f4d66: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "value", type: "uint256", indexed: false } ], name: "Drain", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xddf252ad: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "recipient", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Transfer", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x8c5be1e5: { inputs: [ { name: "owner", type: "address", indexed: true }, { name: "spender", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Approval", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x0f6798a5: { inputs: [ { name: "minter", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Mint", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xcc16f5db: { inputs: [ { name: "burner", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Burn", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x70a08231: { inputs: [ { name: "holderAddress", type: "address" } ], name: "balanceOf", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0xa9059cbb: { inputs: [ { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transfer", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x23b872dd: { inputs: [ { name: "sender", type: "address" }, { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transferFrom", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0xdd62ed3e: { inputs: [ { name: "owner", type: "address" }, { name: "spender", type: "address" } ], name: "allowance", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x095ea7b3: { inputs: [ { name: "spender", type: "address" }, { name: "value", type: "uint256" } ], name: "approve", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x40c10f19: { inputs: [ { name: "userAddress", type: "address" }, { name: "amount", type: "uint256" } ], name: "mint", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x9dc29fac: { inputs: [ { name: "userAddress", type: "address" }, { name: "amount", type: "uint256" } ], name: "burn", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x01ffc9a7: { inputs: [ { name: "interfaceID", type: "bytes4" } ], name: "supportsInterface", outputs: [ { name: "", type: "bool" } ], stateMutability: "view", type: "function" }, 0x8be0079c: { inputs: [ { name: "oldOwner", type: "address", indexed: true }, { name: "newOwner", type: "address", indexed: true } ], name: "OwnershipTransferred", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x893d20e8: { "inputs": [], name: "getOwner", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0xf2fde38b: { inputs: [ { name: "newOwner", type: "address" } ], name: "transferOwnership", "outputs": [], stateMutability: "nonpayable", type: "function" } }, contractName: "WKARMA", storage: { owner: "0x131a190fa22cb867abf58193bf9e7640e9fce682", name: "Wrapped KARMA", symbol: "WKARMA", decimals: 18, totalSupply: "0", "allowed": {}, "balances": {}, supportedInterfaces: { 0x36372b07: true, 0x06fdde03: true, 0x95d89b41: true, 0x313ce567: true }, prototype: { address: "0x2347d36cf0d94b98bab6d6d41c6f94d7214830ad" } }, storageHash: "0xb48d38f93eaa084033fc5970bf96e559c33c4cdc07d889ab00b4d63f9590739d", savedOnBlockNumber: "0" }, 0x0da81b5da0e5b6a4615d3499d31bb34f0e35a74e: { address: "0x0da81b5da0e5b6a4615d3499d31bb34f0e35a74e", balance: "1000000000000000000", "transactions": [], code: "
/*
Name: Faucet Contract
Version: 0.0.3
*/


class Faucet {
allocations = {}; // liste de Allocation : {totalAmount, lastAmount, lastTimestamp} indexée par address
minAmountPerDay = number('10' + '000000000000000000'); // 10
maxAmountPerDay = number('50' + '000000000000000000'); // 50
totalAllocated = number(0);
allocationsDelay = 86400;


Faucet(recipient, amount) {} // event


getFreeMoney(recipient) {
const tokenAllocations = this.allocations || {};

require(address(this).balance.gt(0), "INSUFFICIENT_FAUCET_BALANCE");

if (! recipient) {
_throw('MISSING_SENDER_ADDRESS');
}

if (recipient in tokenAllocations && tokenAllocations[recipient].lastTimestamp > Date.now() - this.allocationsDelay * 1000) {
_throw('TOO_SOON');
}

const diffMinMax = this.maxAmountPerDay.sub(this.minAmountPerDay);
const rnd = Math.round(Math.random() * 1000);
let amount = this.minAmountPerDay.add( diffMinMax.mul(rnd).div(1000) );
//const amount = number('2000000000000000000');

if (amount.lt(this.minAmountPerDay)) {
amount = this.minAmountPerDay;
}

if (amount.gt(address(this).balance)) {
amount = address(this).balance;
}

if (amount.gt(this.maxAmountPerDay)) {
amount = this.maxAmountPerDay;
}

if (! (recipient in tokenAllocations)) {
tokenAllocations[recipient] = {
totalAmount: number(0),
lastAmount: number(0),
lastTimestamp: number(0),
};
}


tokenAllocations[recipient].totalAmount = tokenAllocations[recipient].totalAmount.add(amount);
tokenAllocations[recipient].lastAmount = amount;
tokenAllocations[recipient].lastTimestamp = Date.now();

address(recipient).transfer(amount); // send free money to recipient

address(msg.sender).transfer( number(1e18.toString()) ); // send money for gas payment thanks

this.totalAllocated = this.totalAllocated.add(amount);

emit('Faucet', [recipient, amount]);

return [amount];
}
}

// Events
Faucet.prototype.Faucet.event = true;
Faucet.prototype.Faucet.inputs = ['address indexed', 'uint256'];

// Methods
Faucet.prototype.getFreeMoney.inputs = ['address'];
Faucet.prototype.getFreeMoney.outputs = ['uint256'];


return Faucet;
"
, codeHash: "0x9232aff080256517c36d3d05edd979e7b672e79abb412712af4c65bdf7d84919", codeAbi: { 0xc358234b: { constant: true, "inputs": [], name: "allocations", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x88c53fe6: { constant: true, "inputs": [], name: "minAmountPerDay", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x381fc009: { constant: true, "inputs": [], name: "maxAmountPerDay", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x45f7f249: { constant: true, "inputs": [], name: "totalAllocated", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x2bd99c18: { constant: true, "inputs": [], name: "allocationsDelay", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x1c5347d1: { inputs: [ { name: "recipient", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Faucet", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x418083f9: { inputs: [ { name: "recipient", type: "address" } ], name: "getFreeMoney", outputs: [ { name: "", type: "uint256" } ], stateMutability: "nonpayable", type: "function" } }, contractName: "Faucet", storage: { prototype: { address: "0x0da81b5da0e5b6a4615d3499d31bb34f0e35a74e" }, "allocations": {}, minAmountPerDay: "10000000000000000000", maxAmountPerDay: "50000000000000000000", totalAllocated: "0", allocationsDelay: 86400 }, storageHash: "0xacc567f8900448b11de837128c2b473b7aa4b1ff8532ea3084fb9fc1d64e1fdb", savedOnBlockNumber: "39" }, 0x92c8b8729d850d99c34c50ab2846ec36169e0024: { address: "0x92c8b8729d850d99c34c50ab2846ec36169e0024", balance: "0", "transactions": [], code: "/*
Name: YO Token
Version: 0.0.3
*/


class Ownable {
owner = '0x0000000000000000000000000000000000000000';

OwnershipTransferred(oldOwner, newOwner) {} // event


constructor() {
this.owner = msg.sender;
}

getOwner() {
return [this.owner];
}

transferOwnership(newOwner) {
require(newOwner != address(0), "Ownable: new owner is the zero address");
this._transferOwnership(newOwner);
}

_transferOwnership(newOwner) {
newOwner = newOwner.toLowerCase();
const oldOwner = this.owner;
this.owner = newOwner;
emit('OwnershipTransferred', [oldOwner, newOwner]);
}

_onlyOwner(next) {
require(msg.sender.toLowerCase() == this.owner, 'only owner can execute this');
next();
}
}

// Methods
Ownable.prototype.OwnershipTransferred.event = true;
Ownable.prototype.OwnershipTransferred.inputs = ['address indexed', 'address indexed'];

// Methods
Ownable.prototype.getOwner.view = true;
Ownable.prototype.getOwner.outputs = ['address'];

Ownable.prototype.transferOwnership.inputs = ['address'];
Ownable.prototype.transferOwnership.modifiers = ['_onlyOwner'];

Ownable.prototype._transferOwnership.internal = true;

Ownable.prototype._onlyOwner.internal = true;




class ERC20Token extends Ownable {
name = 'ERC20 Token';
symbol = 'ERC20';
decimals = 18;
totalSupply = number('0');

allowed = {};
balances = {};

supportedInterfaces = {
'0x36372b07': true, // ERC20
'0x06fdde03': true, // ERC20 name
'0x95d89b41': true, // ERC20 symbol
'0x313ce567': true, // ERC20 decimals
};


Transfer(sender, recipient, amount) {} // event
Approval(owner, spender, amount) {} // event
Mint(minter, amount) {} // event
Burn(burner, amount) {} // event


balanceOf(holderAddress) {
holderAddress = holderAddress.toLowerCase();
var tokenBalances = this.balances || {};

if (holderAddress in tokenBalances) {
const balance = tokenBalances[holderAddress];
return [balance];
}
return [number(0)];
}

transfer(recipient, amount) {
recipient = recipient.toLowerCase();
const sender = msg.sender;
var tokenBalances = this.balances || {};

if (! (sender in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}

emit('Transfer', [sender, recipient, amount]);
return [true];
}


transferFrom(sender, recipient, amount) {
sender = sender.toLowerCase();
recipient = recipient.toLowerCase();

var tokenBalances = this.balances || {};
var tokenAllowances = this.allowed || {};

require(sender in tokenBalances, 'MISSING_TOKEN_BALANCE');
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

require(sender == msg.sender || (sender in tokenAllowances && msg.sender in tokenAllowances[sender]), "MISSING_ALLOWANCE");
if (sender != msg.sender && tokenAllowances[sender][msg.sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_ALLOWANCE');
}

tokenAllowances[sender][msg.sender] = tokenAllowances[sender][msg.sender].sub(amount);

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}


emit('Transfer', [sender, recipient, amount]);
return [true];
}


allowance(owner, spender) {
owner = owner.toLowerCase();
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (owner in tokenAllowances && spender in tokenAllowances[owner]) {
return [tokenAllowances[owner][spender]];
}
return [number(0)];
}

approve(spender, value) {
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (! (msg.sender in tokenAllowances)) {
tokenAllowances[msg.sender] = {};
}
tokenAllowances[msg.sender][spender] = value;
emit('Approval', [msg.sender, spender, value]);
return [true];
}


mint(userAddress, amount) {
this._mint(userAddress, amount);
}

_mint(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: mint to the zero address');
}

if (this._incrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.add(amount);
}

emit('Mint', [userAddress, amount]);
}


burn(userAddress, amount) {
this._burn(userAddress, amount);
}

_burn(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: burn from the zero address');
}

if (this._decrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.sub(amount);
}

emit('Burn', [userAddress, amount]);
}


supportsInterface(interfaceID) {
const _interfaces = this.supportedInterfaces || {};
return [
((interfaceID in _interfaces)
? _interfaces[interfaceID]
: false)
];
}


_decrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (amount.gt(tokenBalances[holderAddress])) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].sub(amount);
return true;
}


_incrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
tokenBalances[holderAddress] = number(0);
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].add(amount);
return true;
}

}

// Events
ERC20Token.prototype.Transfer.event = true;
ERC20Token.prototype.Transfer.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Approval.event = true;
ERC20Token.prototype.Approval.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Mint.event = true;
ERC20Token.prototype.Mint.inputs = ['address indexed', 'uint256'];

ERC20Token.prototype.Burn.event = true;
ERC20Token.prototype.Burn.inputs = ['address indexed', 'uint256'];

// Methods
ERC20Token.prototype.balanceOf.view = true;
ERC20Token.prototype.balanceOf.inputs = ['address'];
ERC20Token.prototype.balanceOf.outputs = ['uint256'];

ERC20Token.prototype.transfer.inputs = ['address', 'uint256'];
ERC20Token.prototype.transfer.outputs = ['bool'];

ERC20Token.prototype.transferFrom.inputs = ['address', 'address', 'uint256'];
ERC20Token.prototype.transferFrom.outputs = ['bool'];

ERC20Token.prototype.allowance.view = true;
ERC20Token.prototype.allowance.inputs = ['address', 'address'];
ERC20Token.prototype.allowance.outputs = ['uint256'];

ERC20Token.prototype.approve.inputs = ['address', 'uint256'];
ERC20Token.prototype.approve.outputs = ['bool'];

ERC20Token.prototype.mint.inputs = ['address', 'uint256'];
ERC20Token.prototype.mint.modifiers = ['_onlyOwner'];

ERC20Token.prototype._mint.internal = true;

ERC20Token.prototype.burn.inputs = ['address', 'uint256'];
ERC20Token.prototype.burn.modifiers = ['_onlyOwner'];

ERC20Token.prototype._burn.internal = true;

ERC20Token.prototype.supportsInterface.view = true;
ERC20Token.prototype.supportsInterface.inputs = ['bytes4'];
ERC20Token.prototype.supportsInterface.outputs = ['bool'];

ERC20Token.prototype._decrementUserBalance.internal = true;

ERC20Token.prototype._incrementUserBalance.internal = true;




class YoToken extends ERC20Token {
name = 'YO Token';
symbol = 'YO';

stackingService = '';


initialize(stackingServiceAddress) {
//require(this.stackingService == '', "ALREADY_INITIALIZED");
this.stackingService = stackingServiceAddress.toLowerCase();

const initAmount = number('42000000' + '000000000000000000'); // 42 000 000 YO
this._mint(msg.sender, initAmount);

emit('Initialize', [stackingServiceAddress]);
}


Initialize(stackingServiceAddress) {} // event


mint(recipient, amountToMint) {
require(this.stackingService != '', "NOT_INITIALIZED");
require(msg.sender == this.stackingService, "ONLY_STACKING_SERVICE");
this._mint(recipient, amountToMint);
}

}


// Events
YoToken.prototype.Initialize.event = true;
YoToken.prototype.Initialize.inputs = ['address indexed'];

// Methods
YoToken.prototype.initialize.inputs = ['address'];
//YoToken.prototype.initialize.modifiers = ['_onlyOwner'];

YoToken.prototype.mint.inputs = ['address', 'uint256'];



return YoToken;
"
, codeHash: "0x3f1e692fcf3e652e9a299c1ab9a9874d7376ba1c8e762d31739d3696c385768b", codeAbi: { 0x8da5cb5b: { constant: true, "inputs": [], name: "owner", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0x06fdde03: { constant: true, "inputs": [], name: "name", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x95d89b41: { constant: true, "inputs": [], name: "symbol", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x313ce567: { constant: true, "inputs": [], name: "decimals", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x18160ddd: { constant: true, "inputs": [], name: "totalSupply", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x19e1fca4: { constant: true, "inputs": [], name: "allowed", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x7bb98a68: { constant: true, "inputs": [], name: "balances", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x037cc0e6: { constant: true, "inputs": [], name: "supportedInterfaces", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xa2e78faa: { constant: true, "inputs": [], name: "stackingService", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xc4d66de8: { inputs: [ { name: "stackingServiceAddress", type: "address" } ], name: "initialize", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x36b14535: { inputs: [ { name: "stackingServiceAddress", type: "address", indexed: true } ], name: "Initialize", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xddf252ad: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "recipient", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Transfer", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x8c5be1e5: { inputs: [ { name: "owner", type: "address", indexed: true }, { name: "spender", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Approval", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x0f6798a5: { inputs: [ { name: "minter", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Mint", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xcc16f5db: { inputs: [ { name: "burner", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Burn", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x70a08231: { inputs: [ { name: "holderAddress", type: "address" } ], name: "balanceOf", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0xa9059cbb: { inputs: [ { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transfer", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x23b872dd: { inputs: [ { name: "sender", type: "address" }, { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transferFrom", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0xdd62ed3e: { inputs: [ { name: "owner", type: "address" }, { name: "spender", type: "address" } ], name: "allowance", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x095ea7b3: { inputs: [ { name: "spender", type: "address" }, { name: "value", type: "uint256" } ], name: "approve", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x40c10f19: { inputs: [ { name: "recipient", type: "address" }, { name: "amountToMint", type: "uint256" } ], name: "mint", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x9dc29fac: { inputs: [ { name: "userAddress", type: "address" }, { name: "amount", type: "uint256" } ], name: "burn", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x01ffc9a7: { inputs: [ { name: "interfaceID", type: "bytes4" } ], name: "supportsInterface", outputs: [ { name: "", type: "bool" } ], stateMutability: "view", type: "function" }, 0x8be0079c: { inputs: [ { name: "oldOwner", type: "address", indexed: true }, { name: "newOwner", type: "address", indexed: true } ], name: "OwnershipTransferred", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x893d20e8: { "inputs": [], name: "getOwner", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0xf2fde38b: { inputs: [ { name: "newOwner", type: "address" } ], name: "transferOwnership", "outputs": [], stateMutability: "nonpayable", type: "function" } }, contractName: "YoToken", storage: { prototype: { address: "0x92c8b8729d850d99c34c50ab2846ec36169e0024" }, owner: "0x131a190fa22cb867abf58193bf9e7640e9fce682", name: "YO Token", symbol: "YO", decimals: 18, totalSupply: "42000000000000000000000000", "allowed": {}, balances: { 0xccf8ba457dcad7ee6a0361c96846a0f79744b113: "42000000000000000000000000" }, supportedInterfaces: { 0x36372b07: true, 0x06fdde03: true, 0x95d89b41: true, 0x313ce567: true }, stackingService: "0xc3349025e73b4746d79a30ade1200e5dd2d8f754" }, storageHash: "0xd81debac54db4b3e681b0e2db50d81e0c1be422f0bc8990dd52fb86cceba41bf", savedOnBlockNumber: "11" }, 0xc3349025e73b4746d79a30ade1200e5dd2d8f754: { address: "0xc3349025e73b4746d79a30ade1200e5dd2d8f754", balance: "0", "transactions": [], code: "/*
Name: StackingService
Version: 0.0.3
Source:
- CakeVault : https://github.com/pancakeswap/pancake-smart-contracts/blob/master/projects/cake-vault/contracts/CakeVault.sol
- SmartChefInitializable : https://github.com/pancakeswap/pancake-smart-contracts/blob/master/projects/smartchef/v2/contracts/SmartChefInitializable.sol
- MasterChef : https://github.com/pancakeswap/pancake-smart-contracts/blob/master/projects/farms-pools/contracts/MasterChef.sol
*/


function IERC20(tokenAddress) {
return address(tokenAddress).getContract();
}

function StackerInfo(stackedAmount, rewardDebt) {
this.stackedAmount = stackedAmount || number(0);
this.rewardDebt = rewardDebt || number(0);
}


class StackingService {
owner = ''
stackedToken = '';
rewardToken = '';
totalStacked = number(0);
accRewardPerStackToken = number(0);
stackers = {}; // mapping(address => StackerInfo)
lastMint = number(0);

mintPeriod = number(60 * 1000); // 60 seconds (1 minute)
rewardsPerPeriod = number('100' + '000000000000000000'); // 100 Token emitted per period (splitted on all stackers)



Initialize(stackedToken, rewardToken) {} // event
Reset() {} // event
Deposit(sender, amount) {} // event
Withdrawal(sender, amount, rewardAmount) {} // event
UpdatePool(pendingRewards, extraRewardPerStackToken) {} // event
UpdateStacker(stackerAddress, stackerRewardAmount) {} // event


initialize(stackedToken, rewardToken) {
require(this.stackedToken == '', "ALREADY_INITIALIZED");
this.stackedToken = stackedToken.toLowerCase();
this.rewardToken = rewardToken.toLowerCase();
this.owner = msg.sender;

emit('Initialize', [stackedToken, rewardToken]);
}


reset() {
require(msg.sender == this.owner, 'ONLY_OWNER');
require(this.stackedToken != '', 'NOT_INITIALIZED');
this.stackers = {};
this.totalStacked = number(0);
this.lastMint = number(0);
this.accRewardPerStackToken = number(0);

const [balance1,] = IERC20(this.stackedToken).balanceOf(address(this).address);
if (balance1.gt(0)) {
IERC20(this.stackedToken).transferFrom(address(this).address, msg.sender, balance1);
}

const [balance2,] = IERC20(this.rewardToken).balanceOf(address(this).address);
if (balance2.gt(0)) {
IERC20(this.rewardToken).transferFrom(address(this).address, msg.sender, balance2);
}

emit('Reset', []);
}


balanceOf(stacker) {
stacker = stacker.toLowerCase();
let stackedAmount = number(0);
if (stacker in this.stackers) {
stackedAmount = this.stackers[stacker].stackedAmount;
}
return [stackedAmount];
}


deposit(_amount) {
// stacking
require(this.stackedToken != '', 'NOT_INITIALIZED');
require(_amount.gt(0), 'INVALID_AMOUNT');

if (this.totalStacked.eq(0)) {
this.lastMint = block.timestamp;
}

const _rewardAmount = this.payStackerRewards(msg.sender); // mise a jour de la pool + on encaisse les rewards potentiels, pour repartir sur des comptes à zero à partir de ce deposit

IERC20(this.stackedToken).transferFrom(msg.sender, address(this).address, _amount);

if (! (msg.sender in this.stackers)) {
this.stackers[msg.sender] = new StackerInfo;
}

const stacker = this.stackers[msg.sender];
stacker.stackedAmount = stacker.stackedAmount.add(_amount);

this.totalStacked = this.totalStacked.add(_amount);

stacker.rewardDebt = stacker.stackedAmount.mul(this.accRewardPerStackToken).div(1e12);

//this._earn();

emit('Deposit', [msg.sender, _amount]);
}


withdraw(_amount) {
// unstacking => Withdraw staked tokens and collect reward tokens
require(this.stackedToken != '', 'NOT_INITIALIZED');
require(_amount.gt(0), 'Nothing to withdraw');
require(! _amount.gt(this.totalStacked), 'INSUFFICIENT_TOTAL');
require(msg.sender in this.stackers, 'INVALID_OWNER');
require(! _amount.gt(this.stackers[msg.sender].stackedAmount), 'Withdraw amount exceeds balance');

const _rewardAmount = this.payStackerRewards(msg.sender); // mise a jour de la pool + on encaisse les rewards potentiels, pour repartir sur des comptes à zero à partir de ce withdraw

const stacker = this.stackers[msg.sender];
stacker.stackedAmount = stacker.stackedAmount.sub(_amount);
this.totalStacked = this.totalStacked.sub(_amount);

IERC20(this.stackedToken).transfer(msg.sender, _amount);

stacker.rewardDebt = stacker.stackedAmount.mul(this.accRewardPerStackToken).div(1e12);

emit('Withdrawal', [msg.sender, _amount, _rewardAmount]);
}


getPendingRewards() {
// rewards à minter
let pendingRewards = number(0);

if (this.totalStacked.gt(0)) {
const duration = block.timestamp.sub(this.lastMint); // milliseconds depuis le dernier mint

if (duration.gt(0)) {
const periodsCount = duration.div(this.mintPeriod); // nbPeriods depuis le dernier mint

if (periodsCount.gt(0)) {
pendingRewards = periodsCount.mul(this.rewardsPerPeriod);
}
}
}

return [pendingRewards]; // retourne le nb de rewards POUVANT ÊTRE mintés
}


updatePool() {
const [pendingRewards,] = this.getPendingRewards();
if (pendingRewards.gt(0)) {
this.lastMint = block.timestamp;
IERC20(this.rewardToken).mint(address(this).address, pendingRewards); // on augmente la balance rewardToken (pour le present contract)

const extraRewardPerStackToken = pendingRewards.mul(1e12).div(this.totalStacked);
this.accRewardPerStackToken = this.accRewardPerStackToken.add(extraRewardPerStackToken);

emit('UpdatePool', [pendingRewards, extraRewardPerStackToken]);
}
}


getStackerAvailableRewards(stackerAddress) {
stackerAddress = stackerAddress.toLowerCase();
let stackerRewardAmount = number(0);

const [pendingRewards,] = this.getPendingRewards();

if (stackerAddress in this.stackers) {
const extraRewardPerStackToken = pendingRewards.mul(1e12).div(this.totalStacked);
const accRewardPerStackToken = this.accRewardPerStackToken.add(extraRewardPerStackToken);

const stacker = this.stackers[stackerAddress];
stackerRewardAmount = stacker.stackedAmount.mul(accRewardPerStackToken).div(1e12).sub(stacker.rewardDebt);
}

return [stackerRewardAmount];
}


payStackerRewards(stackerAddress) {
// harvest
stackerAddress = stackerAddress.toLowerCase();

this.updatePool();
const [stackerRewardAmount,] = this._updateStacker(stackerAddress);

return [stackerRewardAmount];
}


_updateStacker(stackerAddress) {
let stackerRewardAmount = number(0);

if (stackerAddress in this.stackers) {
const stacker = this.stackers[stackerAddress];
[stackerRewardAmount, ] = this.getStackerAvailableRewards(stackerAddress);

stacker.rewardDebt = stacker.stackedAmount.mul(this.accRewardPerStackToken).div(1e12);

if (stackerRewardAmount.gt(0)) {
IERC20(this.rewardToken).transfer(stackerAddress, stackerRewardAmount);

emit('UpdateStacker', [stackerAddress, stackerRewardAmount]);
}
}

return [stackerRewardAmount];
}

}

// Events
StackingService.prototype.Initialize.event = true;
StackingService.prototype.Initialize.inputs = ['address indexed', 'address indexed'];

StackingService.prototype.UpdateStacker.event = true;
StackingService.prototype.UpdateStacker.inputs = ['address indexed', 'uint256'];

StackingService.prototype.Reset.event = true;

StackingService.prototype.Deposit.event = true;
StackingService.prototype.Deposit.inputs = ['address indexed', 'uint256'];

StackingService.prototype.Withdrawal.event = true;
StackingService.prototype.Withdrawal.inputs = ['address indexed', 'uint256', 'uint256'];

StackingService.prototype.UpdatePool.event = true;
StackingService.prototype.UpdatePool.inputs = ['uint256', 'uint256'];

StackingService.prototype.UpdateStacker.event = true;
StackingService.prototype.UpdateStacker.inputs = ['address indexed', 'uint256'];

// Methods
StackingService.prototype.initialize.inputs = ['address', 'address'];

StackingService.prototype.balanceOf.view = true;
StackingService.prototype.balanceOf.inputs = ['address'];
StackingService.prototype.balanceOf.outputs = ['uint256'];

StackingService.prototype.deposit.inputs = ['uint256'];

StackingService.prototype.withdraw.inputs = ['uint256'];

StackingService.prototype.getPendingRewards.view = true;
StackingService.prototype.getPendingRewards.outputs = ['uint256'];

StackingService.prototype.getStackerAvailableRewards.view = true;
StackingService.prototype.getStackerAvailableRewards.inputs = ['address'];
StackingService.prototype.getStackerAvailableRewards.outputs = ['uint256'];

StackingService.prototype.payStackerRewards.inputs = ['address'];
StackingService.prototype.payStackerRewards.outputs = ['uint256'];

StackingService.prototype._updateStacker.internal = true;


return StackingService;

"
, codeHash: "0x4abec54ff2c7059d3e4d3a9d0a2500599e6d19caac54fd3d2ee939560fb416e5", codeAbi: { 0x8da5cb5b: { constant: true, "inputs": [], name: "owner", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x5b5c0f23: { constant: true, "inputs": [], name: "stackedToken", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xf7c618c1: { constant: true, "inputs": [], name: "rewardToken", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x29eae70d: { constant: true, "inputs": [], name: "totalStacked", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x585dd2e4: { constant: true, "inputs": [], name: "accRewardPerStackToken", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x834ea32d: { constant: true, "inputs": [], name: "stackers", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x586fc5b5: { constant: true, "inputs": [], name: "lastMint", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x4c498203: { constant: true, "inputs": [], name: "mintPeriod", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x978db419: { constant: true, "inputs": [], name: "rewardsPerPeriod", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xdc90fed0: { inputs: [ { name: "stackedToken", type: "address", indexed: true }, { name: "rewardToken", type: "address", indexed: true } ], name: "Initialize", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x6423db34: { "inputs": [], name: "Reset", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xe1fffcc4: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Deposit", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xdf273cb6: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false }, { name: "rewardAmount", type: "uint256", indexed: false } ], name: "Withdrawal", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xb35b339e: { inputs: [ { name: "pendingRewards", type: "uint256", indexed: false }, { name: "extraRewardPerStackToken", type: "uint256", indexed: false } ], name: "UpdatePool", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xc063ef91: { inputs: [ { name: "stackerAddress", type: "address", indexed: true }, { name: "stackerRewardAmount", type: "uint256", indexed: false } ], name: "UpdateStacker", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x485cc955: { inputs: [ { name: "stackedToken", type: "address" }, { name: "rewardToken", type: "address" } ], name: "initialize", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0xd826f88f: { "inputs": [], name: "reset", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x70a08231: { inputs: [ { name: "stacker", type: "address" } ], name: "balanceOf", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0xb6b55f25: { inputs: [ { name: "_amount", type: "uint256" } ], name: "deposit", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x2e1a7d4d: { inputs: [ { name: "_amount", type: "uint256" } ], name: "withdraw", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0xd9621f9e: { "inputs": [], name: "getPendingRewards", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0xe3161ddd: { "inputs": [], name: "updatePool", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x6e4b5056: { inputs: [ { name: "stackerAddress", type: "address" } ], name: "getStackerAvailableRewards", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x04c57c17: { inputs: [ { name: "stackerAddress", type: "address" } ], name: "payStackerRewards", outputs: [ { name: "", type: "uint256" } ], stateMutability: "nonpayable", type: "function" } }, contractName: "StackingService", storage: { prototype: { address: "0xc3349025e73b4746d79a30ade1200e5dd2d8f754" }, owner: "0xccf8ba457dcad7ee6a0361c96846a0f79744b113", stackedToken: "0x2347d36cf0d94b98bab6d6d41c6f94d7214830ad", rewardToken: "0x92c8b8729d850d99c34c50ab2846ec36169e0024", totalStacked: "0", accRewardPerStackToken: "0", "stackers": {}, lastMint: "0", mintPeriod: "60000", rewardsPerPeriod: "100000000000000000000" }, storageHash: "0x5a50fe34cf2ae9d8f44abe7c1f52bd1095fe10415487b5143d6dcadad1774bb1", savedOnBlockNumber: "12" }, 0x0a4c2f3a68f3f43999ece62605d5743ab600fda9: { address: "0x0a4c2f3a68f3f43999ece62605d5743ab600fda9", balance: "0", "transactions": [], code: "
/*
Name: YO NFT
Version: 0.0.3
*/


function IERC721Receiver(tokenAddress) {
return address(tokenAddress).getContract();
}


class ERC721Receiver {
onERC721Received(operator, from, tokenId, data) {
const selector = '0xa8fcc417'; // onERC721Received
return [selector];
};
}

ERC721Receiver.prototype.onERC721Received.inputs = ['address', 'address', 'uint256', 'bytes'];
ERC721Receiver.prototype.onERC721Received.outputs = ['bytes4'];



class ERC721 extends ERC721Receiver {
name = '';
symbol = '';
decimals = number(0);

owners = {}; // mapping(uint256 => address)
balances = {}; // mapping(address => uint256)
tokenApprovals = {}; // mapping(uint256 => address)
operatorApprovals = {}; // mapping(address => mapping(address => bool))


Mint(minter, to, tokenId) {} // event
Burn() {owner, burner, tokenId} // event
Transfer(from, to, tokenId) {} // event
Approval(owner, approved, tokenId) {} // event
ApprovalForAll(owner, operator, approved) {} // event


constructor(name, symbol) {
super();
this.name = name;
this.symbol = symbol;
}


supportsInterface(interfaceId) {
//const result = interfaceId == '0x80ac58cd' || interfaceId == '0x5b5e139f' || super.supportsInterface(interfaceId);
const result = (interfaceId == '0x80ac58cd' || interfaceId == '0x5b5e139f');
return [result];
}


balanceOf(owner) {
owner = owner.toLowerCase();
require(owner != address(0).address, "ERC721: address zero is not a valid owner");
if (owner in this.balances) {
return [this.balances[owner]];
}
return [Number(0)];
}


ownerOf(tokenId) {
require(tokenId in this.owners, "ERC721: owner query for nonexistent token");
const owner = this.owners[tokenId];
return [owner];
}


tokenURI(tokenId) {
require(this._exists(tokenId)[0], "ERC721Metadata: URI query for nonexistent token");

const baseURI = this.baseURI()[0];
const _tokenUri = baseURI.length > 0 ? (baseURI + tokenId.toString()) : "";
return [_tokenUri];
}


_baseURI() {
return [""];
}


approve(to, tokenId) {
to = to.toLowerCase();
require(this._exists(tokenId)[0], "ERC721: approval nonexistent token");
const owner = this.ownerOf(tokenId)[0];
require(to != owner, "ERC721: approval to current owner");

require(
msg.sender == owner || this.isApprovedForAll(owner, msg.sender)[0],
"ERC721: approve caller is not owner nor approved for all"
);

this._approve(to, tokenId);
}


getApproved(tokenId) {
require(this._exists(tokenId)[0], "ERC721: approved query for nonexistent token");

if (tokenId in this.tokenApprovals) {
return [ this.tokenApprovals[tokenId] ];
}

return [ number(0) ];
}


setApprovalForAll(operator, approved) {
operator = operator.toLowerCase();
this._setApprovalForAll(msg.sender, operator, approved);
}


isApprovedForAll(owner, operator) {
owner = owner.toLowerCase();
operator = operator.toLowerCase();
if (owner in this.operatorApprovals && operator in this.operatorApprovals[owner]) {
return [ this.operatorApprovals[owner][operator] ];
}
return [false];
}


transferFrom(from, to, tokenId) {
from = from.toLowerCase();
to = to.toLowerCase();
require(this._isApprovedOrOwner(msg.sender, tokenId)[0], "ERC721: transfer caller is not owner nor approved");
this._transfer(from, to, tokenId);
}


safeTransferFrom(from, to, tokenId, _data) {
from = from.toLowerCase();
to = to.toLowerCase();
require(this._isApprovedOrOwner(msg.sender, tokenId)[0], "ERC721: transfer caller is not owner nor approved");
this._safeTransfer(from, to, tokenId, _data);
}


_safeTransfer(from, to, tokenId, _data) {
from = from.toLowerCase();
to = to.toLowerCase();
this._transfer(from, to, tokenId);
require(this._checkOnERC721Received(from, to, tokenId, _data)[0], "ERC721: transfer to non ERC721Receiver implementer");
}


_exists(tokenId) {
return [ tokenId in this.owners ];
}


_isApprovedOrOwner(spender, tokenId) {
spender = spender.toLowerCase();
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
const owner = this.ownerOf(tokenId)[0];
const result = (spender == owner || this.isApprovedForAll(owner, spender)[0] || this.getApproved(tokenId)[0] == spender);
return [result];
}


_safeMint(to, tokenId, _data) {
to = to.toLowerCase();
this._mint(to, tokenId);
require(
this._checkOnERC721Received(address(0).address, to, tokenId, _data)[0],
"ERC721: transfer to non ERC721Receiver implementer"
);
}


_mint(to, tokenId) {
to = to.toLowerCase();
require(to != address(0).address, "ERC721: mint to the zero address");
require(!this._exists(tokenId)[0], "ERC721: token already minted");

this._beforeTokenTransfer(address(0).address, to, tokenId);

this.balances[to] = this.balances[to] || number(0);
this.balances[to] = this.balances[to].add(1);
this.owners[tokenId] = to;

emit('Mint', [address(0).address, to, tokenId]);

this._afterTokenTransfer(address(0).address, to, tokenId);
}


_burn(tokenId) {
const owner = this.ownerOf(tokenId)[0];

this._beforeTokenTransfer(owner, address(0).address, tokenId);

// Clear approvals
this._approve(address(0).address, tokenId);

this.balances[owner] = this.balances[owner].sub(1);
delete this.owners[tokenId];

emit('Burn', [owner, address(0).address, tokenId]);

_afterTokenTransfer(owner, address(0).address, tokenId);
}


_transfer(from, to, tokenId) {
from = from.toLowerCase();
to = to.toLowerCase();
require(this.ownerOf(tokenId)[0] == from, "ERC721: transfer from incorrect owner");
require(to != address(0).address, "ERC721: transfer to the zero address");

this._beforeTokenTransfer(from, to, tokenId);

// Clear approvals from the previous owner
this._approve(address(0).address, tokenId);

this.balances[from] = this.balances[from].sub(1);
this.balances[to] = this.balances[to] || number(0);
this.balances[to] = this.balances[to].add(1);
this.owners[tokenId] = to;

emit('Transfer', [from, to, tokenId]);

this._afterTokenTransfer(from, to, tokenId);
}


_approve(approved, tokenId) {
approved = approved.toLowerCase();
this.tokenApprovals[tokenId] = approved;
emit('Approval', [this.ownerOf(tokenId)[0], approved, tokenId]);
}


_setApprovalForAll(owner, operator, approved) {
owner = owner.toLowerCase();
operator = operator.toLowerCase();
require(owner != operator, "ERC721: approve to caller");
if (! (owner in this.operatorApprovals)) {
this.operatorApprovals[owner] = {};
}
this.operatorApprovals[owner][operator] = approved;
emit('ApprovalForAll', [owner, operator, approved]);
}


_checkOnERC721Received(from, to, tokenId, _data) {
from = from.toLowerCase();
to = to.toLowerCase();
if (address(to).isContract()) {
try {
const retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data)[0];
const selector = '0xa8fcc417'; // onERC721Received
return [retval == selector];

} catch (e) {
const reason = e.message;
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");

} else {
revert(reason);
}
}

} else {
return [true];
}
}


_beforeTokenTransfer(from, to, tokenId) {
}

_afterTokenTransfer(from, to, tokenId) {
}

}

// Events
ERC721.prototype.Mint.event = true;
ERC721.prototype.Mint.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC721.prototype.Burn.event = true;
ERC721.prototype.Burn.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC721.prototype.Transfer.event = true;
ERC721.prototype.Transfer.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC721.prototype.Approval.event = true;
ERC721.prototype.Approval.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC721.prototype.ApprovalForAll.event = true;
ERC721.prototype.ApprovalForAll.inputs = ['address indexed', 'address indexed', 'uint256'];

// Methods
ERC721.prototype.supportsInterface.view = true;
ERC721.prototype.supportsInterface.inputs = ['bytes4'];
ERC721.prototype.supportsInterface.outputs = ['bool'];

ERC721.prototype.balanceOf.view = true;
ERC721.prototype.balanceOf.inputs = ['address'];
ERC721.prototype.balanceOf.outputs = ['uint256'];

ERC721.prototype.ownerOf.view = true;
ERC721.prototype.ownerOf.inputs = ['uint256'];
ERC721.prototype.ownerOf.outputs = ['address'];

ERC721.prototype.tokenURI.view = true;
ERC721.prototype.tokenURI.inputs = ['uint256'];
ERC721.prototype.tokenURI.outputs = ['string'];

ERC721.prototype._baseURI.internal = true;

ERC721.prototype.approve.inputs = ['address', 'uint256'];

ERC721.prototype.getApproved.view = true;
ERC721.prototype.getApproved.outputs = ['address'];

ERC721.prototype.setApprovalForAll.inputs = ['address', 'bool'];

ERC721.prototype.isApprovedForAll.view = true;
ERC721.prototype.isApprovedForAll.inputs = ['address', 'address'];

ERC721.prototype.transferFrom.inputs = ['address', 'address', 'uint256'];

ERC721.prototype.safeTransferFrom.inputs = ['address', 'address', 'uint256', 'bytes'];

ERC721.prototype._safeTransfer.internal = true;

ERC721.prototype._exists.internal = true;

ERC721.prototype._isApprovedOrOwner.internal = true;

ERC721.prototype._safeMint.internal = true;

ERC721.prototype._mint.internal = true;

ERC721.prototype._burn.internal = true;

ERC721.prototype._transfer.internal = true;

ERC721.prototype._approve.internal = true;

ERC721.prototype._setApprovalForAll.internal = true;

ERC721.prototype._checkOnERC721Received.private = true;

ERC721.prototype._beforeTokenTransfer.internal = true;

ERC721.prototype._afterTokenTransfer.internal = true;





class YoNFT extends ERC721 {
name = 'YO NFT';
symbol = 'YoNFT';

_tokenIds = 0;
_MAX_SUPPLY = 10;

mintprice = number('1' + '000000000000000000'); // 1 ether


_baseURI() {
const baseURI = 'http://localhost:8545/collections/' + address(this).address + '/';
return [ baseURI ];
}

tokenURI(tokenId) {
require(this._exists(tokenId)[0], "ERC721Metadata: URI query for nonexistent token");

const baseURI = this.baseURI()[0];
const _tokenUri = baseURI.length > 0 ? (baseURI + tokenId.toString() + '.json') : "";
return [_tokenUri];
}

mint(receiver) {
require(this._tokenIds < this._MAX_SUPPLY, 'Max supply reached');
require(msg.value.eq(this.mintprice), 'Invalid price');
this._tokenIds++;

const newNftTokenId = this._tokenIds;
this._safeMint(receiver, newNftTokenId, '');

return [newNftTokenId];
}
}

// Methods
YoNFT.prototype.tokenURI.inputs = ['uint256'];
YoNFT.prototype.tokenURI.outputs = ['string'];
YoNFT.prototype.tokenURI.view = true;

YoNFT.prototype.mint.inputs = ['address'];
YoNFT.prototype.mint.outputs = ['uint256'];
YoNFT.prototype.mint.modifiers = ['onlyOwner'];
YoNFT.prototype.mint.payable = true;


return YoNFT;
"
, codeHash: "0xe4a23e6b844c15d980c4a4510d94b4928d7a871db5358a6dd2b0f09cfdf61ef1", codeAbi: { 0x06fdde03: { constant: true, "inputs": [], name: "name", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x95d89b41: { constant: true, "inputs": [], name: "symbol", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x313ce567: { constant: true, "inputs": [], name: "decimals", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0xaffe39c1: { constant: true, "inputs": [], name: "owners", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x7bb98a68: { constant: true, "inputs": [], name: "balances", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x2369fde5: { constant: true, "inputs": [], name: "tokenApprovals", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x771149fc: { constant: true, "inputs": [], name: "operatorApprovals", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x88eab676: { constant: true, "inputs": [], name: "mintprice", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x6a627842: { inputs: [ { name: "receiver", type: "address" } ], name: "mint", outputs: [ { name: "", type: "uint256" } ], stateMutability: "payable", type: "function" }, 0xab8530f8: { inputs: [ { name: "minter", type: "address", indexed: true }, { name: "to", type: "address", indexed: true }, { name: "tokenId", type: "uint256", indexed: false } ], name: "Mint", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x396ed0ab: { "inputs": [], name: "Burn", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xddf252ad: { inputs: [ { name: "from", type: "address", indexed: true }, { name: "to", type: "address", indexed: true }, { name: "tokenId", type: "uint256", indexed: false } ], name: "Transfer", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x8c5be1e5: { inputs: [ { name: "owner", type: "address", indexed: true }, { name: "approved", type: "address", indexed: true }, { name: "tokenId", type: "uint256", indexed: false } ], name: "Approval", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x935230e6: { inputs: [ { name: "owner", type: "address", indexed: true }, { name: "operator", type: "address", indexed: true }, { name: "approved", type: "uint256", indexed: false } ], name: "ApprovalForAll", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x01ffc9a7: { inputs: [ { name: "interfaceId", type: "bytes4" } ], name: "supportsInterface", outputs: [ { name: "", type: "bool" } ], stateMutability: "view", type: "function" }, 0x70a08231: { inputs: [ { name: "owner", type: "address" } ], name: "balanceOf", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x6352211e: { inputs: [ { name: "tokenId", type: "uint256" } ], name: "ownerOf", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0xc87b56dd: { inputs: [ { name: "tokenId", type: "uint256" } ], name: "tokenURI", outputs: [ { name: "", type: "string" } ], stateMutability: "view", type: "function" }, 0x095ea7b3: { inputs: [ { name: "to", type: "address" }, { name: "tokenId", type: "uint256" } ], name: "approve", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x081812fc: { inputs: [ { name: "tokenId", type: "uint256" } ], name: "getApproved", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0xa22cb465: { inputs: [ { name: "operator", type: "address" }, { name: "approved", type: "bool" } ], name: "setApprovalForAll", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0xe985e9c5: { inputs: [ { name: "owner", type: "address" }, { name: "operator", type: "address" } ], name: "isApprovedForAll", "outputs": [], stateMutability: "view", type: "function" }, 0x23b872dd: { inputs: [ { name: "from", type: "address" }, { name: "to", type: "address" }, { name: "tokenId", type: "uint256" } ], name: "transferFrom", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0xb88d4fde: { inputs: [ { name: "from", type: "address" }, { name: "to", type: "address" }, { name: "tokenId", type: "uint256" }, { name: "_data", type: "bytes" } ], name: "safeTransferFrom", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x150b7a02: { inputs: [ { name: "operator", type: "address" }, { name: "from", type: "address" }, { name: "tokenId", type: "uint256" }, { name: "data", type: "bytes" } ], name: "onERC721Received", outputs: [ { name: "", type: "bytes4" } ], stateMutability: "nonpayable", type: "function" } }, contractName: "YoNFT", storage: { name: "YO NFT", symbol: "YoNFT", decimals: "0", "owners": {}, "balances": {}, "tokenApprovals": {}, "operatorApprovals": {}, _tokenIds: 0, _MAX_SUPPLY: 10, mintprice: "1000000000000000000", prototype: { address: "0x0a4c2f3a68f3f43999ece62605d5743ab600fda9" } }, storageHash: "0xb48d38f93eaa084033fc5970bf96e559c33c4cdc07d889ab00b4d63f9590739d", savedOnBlockNumber: "4" }, 0x73f7dafa086d58aedd8146f40dd8a86fcf778b8f: { address: "0x73f7dafa086d58aedd8146f40dd8a86fcf778b8f", balance: "0", "transactions": [], code: "/*
Name: Hot Potatoe
Version: 0.0.3
*/


class HotPotatoe {
name = 'HOT Potatoe';
symbol = 'POTATOE';

decimals = 0;
totalSupply = number('0');

initPrice = number('1' + '000000000000000000'); // 1 ether
admin = '';

PotatoeType = {
idx: number(0),
minter: '',
owner: '',
debtor: '',
price: number(0),
parentIdx: number(-1),
initDate: number(0),
transfers: number(0),
cumulativePrice: number(0),
};

potatoes = []; // array of Potatoe
participants = {}; // mapping (address participant => mapping(uint256 potatoeIdx => string role))


Initialize(minterAddress) {} // event
Mint(potatoeIdx, minter) {} // event
Transfer(potatoeIdx, sender, to) {} // event
Steal(potatoeIdx, stealer) {} // event
Withdrawal(amount) {} // event


constructor() {
this.admin = msg.sender;
}

initialize() {
//require(msg.sender == this.admin, "ONLY_ADMIN");
require(this.potatoes.length == 0, "ONLY_ONCE");
this._mint(msg.sender, -1);

emit('Initialize', [msg.sender]);
}


potatoesCount() {
return [this.potatoes.length];
}

_mint(minter, parentIdx) {
minter = minter.toLowerCase();
const potatoeIdx = this.potatoes.length;

const potatoe = {
idx: potatoeIdx,
minter,
owner: address(this).address,
debtor: minter,
price: this.initPrice,
parentIdx,
initDate: number(block.timestamp),
transfers: number(0),
cumulativePrice: number(0),
};
this.potatoes.push(potatoe);
this._setHolding(minter, potatoeIdx, 'minter+debtor');
this.totalSupply = this.totalSupply.add(1);

emit('Mint', [potatoeIdx, minter]);
}

_nextPrice(currentPrice) {
const rewardPercent = number(150); // 150%
const price = currentPrice.mul(rewardPercent).div(100);
return [price];
}

price(potatoeIdx) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];
const price = potatoe.price;
return [price];
}

nextPrice(potatoeIdx) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];
const price = this._nextPrice(potatoe.price)[0];
return [price];
}

owner(potatoeIdx) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];
const owner = potatoe.owner;
return [owner];
}

debtor(potatoeIdx) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];
const debtor = potatoe.debtor;
return [debtor];
}

transfer(potatoeIdx, to) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];

const sender = msg.sender.toLowerCase();
require(potatoe.debtor == sender, "ONLY_DEBTOR");

require(address(this) != to, "INVALID_TARGET");
require(address(0) != to, "INVALID_TARGET");

to = to.toLowerCase();
require(potatoe.owner != to, "NO_BACKTRACK_TO_OWNER");
require(potatoe.minter != to, "NO_BACKTRACK_TO_MINTER");

const price = potatoe.price;
require(price.eq(msg.value), "INVALID_POTATOE_PRICE");

const treasureFees = msg.value.mul(1).div(1000); // 0.1% fees for the treasure
const minterFees = msg.value.mul(9).div(1000); // 0.9% fees for the minter
address(potatoe.minter).transfer(minterFees);
address(potatoe.owner).transfer(msg.value.sub(treasureFees).sub(minterFees)); // repay (+bonus-fees) the previous owner

if (potatoe.owner == potatoe.minter) {
this._setHolding(potatoe.owner, potatoeIdx, 'minter+retired');
} else if (potatoe.owner != address(this).address) {
this._setHolding(potatoe.owner, potatoeIdx, 'retired');
}

if (sender == potatoe.minter) {
this._setHolding(sender, potatoeIdx, 'minter+owner');
} else {
this._setHolding(sender, potatoeIdx, 'owner');
}

if (to == potatoe.minter) {
this._setHolding(to, potatoeIdx, 'minter+debtor');
} else {
this._setHolding(to, potatoeIdx, 'debtor');
}

potatoe.owner = sender; // new owner (old debtor)
potatoe.debtor = to; // new debtor
potatoe.transfers = potatoe.transfers.add(1);

if (sender != to) {
potatoe.cumulativePrice = potatoe.cumulativePrice.add(msg.value);
}

const newPrice = this._nextPrice(price)[0];
potatoe.price = newPrice; // new price

emit('Transfer', [potatoeIdx, sender, to]);

this._mint(msg.sender, potatoe.idx);
}

holdings(participantAddress) {
participantAddress = participantAddress.toLowerCase();
require(participantAddress in this.participants, "INVALID_PARTICIPANT");

const result = Object.entries(this.participants[participantAddress]).map((entry => {
const [potatoeIdx, role] = entry;
return potatoeIdx + ':' + role;
})).join(' ');
return [result];
}

_setHolding(participantAddress, potatoeIdx, role) {
participantAddress = participantAddress.toLowerCase();
if (! (participantAddress in this.participants)) {
this.participants[participantAddress] = {};
}
this.participants[participantAddress][potatoeIdx] = role;
}

steal(potatoeIdx) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];

const stealer = msg.sender.toLowerCase();
require(potatoe.owner != stealer, "INVALID_STEALER_OWNER");
require(potatoe.debtor != stealer, "INVALID_STEALER_DEBTOR");

const _stealPrice = this.nextPrice(potatoeIdx)[0];
require(_stealPrice.eq(msg.value), "INVALID_POTATOE_STEAL_PRICE");

potatoe.owner = stealer; // stealer is now the owner => he will not pay the transfer (transfer to himself)
potatoe.debtor = stealer;
potatoe.price = _stealPrice;

potatoe.cumulativePrice = potatoe.cumulativePrice.add(msg.value);

this._setHolding(stealer, potatoeIdx, 'stealer');

emit('Steal', [potatoeIdx, stealer]);
}

withdraw(amount) {
require(msg.sender == this.admin, "ONLY_ADMIN");
address(this.admin).transfer(amount);
emit('Withdrawal', [amount]);
}

}

// Events
HotPotatoe.prototype.Initialize.event = true;
HotPotatoe.prototype.Initialize.inputs = ['address indexed'];

HotPotatoe.prototype.Mint.event = true;
HotPotatoe.prototype.Mint.inputs = ['uint256 indexed', 'address indexed'];

HotPotatoe.prototype.Transfer.event = true;
HotPotatoe.prototype.Transfer.inputs = ['uint256 indexed', 'address indexed', 'address indexed'];

HotPotatoe.prototype.Steal.event = true;
HotPotatoe.prototype.Steal.inputs = ['uint256 indexed', 'address indexed'];

HotPotatoe.prototype.Withdrawal.event = true;
HotPotatoe.prototype.Withdrawal.inputs = ['uint256'];


// Methods
HotPotatoe.prototype._mint.internal = true;

HotPotatoe.prototype._nextPrice.internal = true;

HotPotatoe.prototype.transfer.payable = true;
HotPotatoe.prototype.transfer.inputs = ['uint256', 'address'];

HotPotatoe.prototype.price.view = true;
HotPotatoe.prototype.price.inputs = ['uint256'];
HotPotatoe.prototype.price.outputs = ['uint256'];

HotPotatoe.prototype.potatoesCount.view = true;
HotPotatoe.prototype.potatoesCount.outputs = ['uint256'];

HotPotatoe.prototype.nextPrice.view = true;
HotPotatoe.prototype.nextPrice.inputs = ['uint256'];
HotPotatoe.prototype.nextPrice.outputs = ['uint256'];

HotPotatoe.prototype.owner.view = true;
HotPotatoe.prototype.owner.inputs = ['uint256'];
HotPotatoe.prototype.owner.outputs = ['address'];

HotPotatoe.prototype.debtor.view = true;
HotPotatoe.prototype.debtor.inputs = ['uint256'];
HotPotatoe.prototype.debtor.outputs = ['address'];

HotPotatoe.prototype.holdings.view = true;
HotPotatoe.prototype.holdings.inputs = ['address'];
HotPotatoe.prototype.holdings.outputs = ['string'];

HotPotatoe.prototype._setHolding.internal = true;

HotPotatoe.prototype.steal.payable = true;
HotPotatoe.prototype.steal.inputs = ['uint256'];

HotPotatoe.prototype.withdraw.inputs = ['uint256'];

return HotPotatoe;
"
, codeHash: "0x38bfd1abf92e59c02ef1cf580e5f0310eb66202c827d72430dda08a6f357d703", codeAbi: { 0x06fdde03: { constant: true, "inputs": [], name: "name", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x95d89b41: { constant: true, "inputs": [], name: "symbol", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x313ce567: { constant: true, "inputs": [], name: "decimals", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x18160ddd: { constant: true, "inputs": [], name: "totalSupply", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0xb6add0f4: { constant: true, "inputs": [], name: "initPrice", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0xf851a440: { constant: true, "inputs": [], name: "admin", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0xaa7b0928: { constant: true, "inputs": [], name: "PotatoeType", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x1b5b0f01: { constant: true, "inputs": [], name: "potatoes", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x6c4470fb: { constant: true, "inputs": [], name: "participants", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x36b14535: { inputs: [ { name: "minterAddress", type: "address", indexed: true } ], name: "Initialize", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xf3cea549: { inputs: [ { name: "potatoeIdx", type: "uint256", indexed: true }, { name: "minter", type: "address", indexed: true } ], name: "Mint", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x0a429aba: { inputs: [ { name: "potatoeIdx", type: "uint256", indexed: true }, { name: "sender", type: "address", indexed: true }, { name: "to", type: "address", indexed: true } ], name: "Transfer", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xab64b03a: { inputs: [ { name: "potatoeIdx", type: "uint256", indexed: true }, { name: "stealer", type: "address", indexed: true } ], name: "Steal", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x4e70a604: { inputs: [ { name: "amount", type: "uint256", indexed: false } ], name: "Withdrawal", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x8129fc1c: { "inputs": [], name: "initialize", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0xf469c89c: { "inputs": [], name: "potatoesCount", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x26a49e37: { inputs: [ { name: "potatoeIdx", type: "uint256" } ], name: "price", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x2821ca71: { inputs: [ { name: "potatoeIdx", type: "uint256" } ], name: "nextPrice", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0xa123c33e: { inputs: [ { name: "potatoeIdx", type: "uint256" } ], name: "owner", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0x10361897: { inputs: [ { name: "potatoeIdx", type: "uint256" } ], name: "debtor", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0xb7760c8f: { inputs: [ { name: "potatoeIdx", type: "uint256" }, { name: "to", type: "address" } ], name: "transfer", "outputs": [], stateMutability: "payable", type: "function" }, 0xdd3ced63: { inputs: [ { name: "participantAddress", type: "address" } ], name: "holdings", outputs: [ { name: "", type: "string" } ], stateMutability: "view", type: "function" }, 0x9bcf5f0c: { inputs: [ { name: "potatoeIdx", type: "uint256" } ], name: "steal", "outputs": [], stateMutability: "payable", type: "function" }, 0x2e1a7d4d: { inputs: [ { name: "amount", type: "uint256" } ], name: "withdraw", "outputs": [], stateMutability: "nonpayable", type: "function" } }, contractName: "HotPotatoe", storage: { prototype: { address: "0x73f7dafa086d58aedd8146f40dd8a86fcf778b8f" }, name: "HOT Potatoe", symbol: "POTATOE", decimals: 0, totalSupply: "1", initPrice: "1000000000000000000", admin: "0x131a190fa22cb867abf58193bf9e7640e9fce682", PotatoeType: { idx: "0", minter: "", owner: "", debtor: "", price: "0", parentIdx: "-1", initDate: "0", transfers: "0", cumulativePrice: "0" }, potatoes: [ { idx: 0, minter: "0xccf8ba457dcad7ee6a0361c96846a0f79744b113", owner: "0x73f7dafa086d58aedd8146f40dd8a86fcf778b8f", debtor: "0xccf8ba457dcad7ee6a0361c96846a0f79744b113", price: "1000000000000000000", parentIdx: -1, initDate: "1651573347208", transfers: "0", cumulativePrice: "0" } ], participants: { 0xccf8ba457dcad7ee6a0361c96846a0f79744b113: { 0: "minter+debtor" } } }, storageHash: "0xb5193f92ac3d5c5c6b4f34b77b9d11cc38fc5d8508236e345904b6556ba232b6", savedOnBlockNumber: "13" }, 0xce7e65b9cfadb8cb904b757f263297aa29988fe7: { address: "0xce7e65b9cfadb8cb904b757f263297aa29988fe7", balance: "0", "transactions": [], code: "/*
Name: DoubleOrQuits Token
Version: 0.0.3
*/


class Ownable {
owner = '0x0000000000000000000000000000000000000000';

OwnershipTransferred(oldOwner, newOwner) {} // event


constructor() {
this.owner = msg.sender;
}

getOwner() {
return [this.owner];
}

transferOwnership(newOwner) {
require(newOwner != address(0), "Ownable: new owner is the zero address");
this._transferOwnership(newOwner);
}

_transferOwnership(newOwner) {
newOwner = newOwner.toLowerCase();
const oldOwner = this.owner;
this.owner = newOwner;
emit('OwnershipTransferred', [oldOwner, newOwner]);
}

_onlyOwner(next) {
require(msg.sender.toLowerCase() == this.owner, 'only owner can execute this');
next();
}
}

// Methods
Ownable.prototype.OwnershipTransferred.event = true;
Ownable.prototype.OwnershipTransferred.inputs = ['address indexed', 'address indexed'];

// Methods
Ownable.prototype.getOwner.view = true;
Ownable.prototype.getOwner.outputs = ['address'];

Ownable.prototype.transferOwnership.inputs = ['address'];
Ownable.prototype.transferOwnership.modifiers = ['_onlyOwner'];

Ownable.prototype._transferOwnership.internal = true;

Ownable.prototype._onlyOwner.internal = true;




class ERC20Token extends Ownable {
name = 'ERC20 Token';
symbol = 'ERC20';
decimals = 18;
totalSupply = number('0');

allowed = {};
balances = {};

supportedInterfaces = {
'0x36372b07': true, // ERC20
'0x06fdde03': true, // ERC20 name
'0x95d89b41': true, // ERC20 symbol
'0x313ce567': true, // ERC20 decimals
};


Transfer(sender, recipient, amount) {} // event
Approval(owner, spender, amount) {} // event
Mint(minter, amount) {} // event
Burn(burner, amount) {} // event


balanceOf(holderAddress) {
holderAddress = holderAddress.toLowerCase();
var tokenBalances = this.balances || {};

if (holderAddress in tokenBalances) {
const balance = tokenBalances[holderAddress];
return [balance];
}
return [number(0)];
}

transfer(recipient, amount) {
recipient = recipient.toLowerCase();
const sender = msg.sender;
var tokenBalances = this.balances || {};

if (! (sender in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}

emit('Transfer', [sender, recipient, amount]);
return [true];
}


transferFrom(sender, recipient, amount) {
sender = sender.toLowerCase();
recipient = recipient.toLowerCase();

var tokenBalances = this.balances || {};
var tokenAllowances = this.allowed || {};

require(sender in tokenBalances, 'MISSING_TOKEN_BALANCE');
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

require(sender == msg.sender || (sender in tokenAllowances && msg.sender in tokenAllowances[sender]), "MISSING_ALLOWANCE");
if (sender != msg.sender && tokenAllowances[sender][msg.sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_ALLOWANCE');
}

tokenAllowances[sender][msg.sender] = tokenAllowances[sender][msg.sender].sub(amount);

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}


emit('Transfer', [sender, recipient, amount]);
return [true];
}


allowance(owner, spender) {
owner = owner.toLowerCase();
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (owner in tokenAllowances && spender in tokenAllowances[owner]) {
return [tokenAllowances[owner][spender]];
}
return [number(0)];
}

approve(spender, value) {
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (! (msg.sender in tokenAllowances)) {
tokenAllowances[msg.sender] = {};
}
tokenAllowances[msg.sender][spender] = value;
emit('Approval', [msg.sender, spender, value]);
return [true];
}


mint(userAddress, amount) {
this._mint(userAddress, amount);
}

_mint(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: mint to the zero address');
}

if (this._incrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.add(amount);
}

emit('Mint', [userAddress, amount]);
}


burn(userAddress, amount) {
this._burn(userAddress, amount);
}

_burn(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: burn from the zero address');
}

if (this._decrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.sub(amount);
}

emit('Burn', [userAddress, amount]);
}


supportsInterface(interfaceID) {
const _interfaces = this.supportedInterfaces || {};
return [
((interfaceID in _interfaces)
? _interfaces[interfaceID]
: false)
];
}


_decrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (amount.gt(tokenBalances[holderAddress])) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].sub(amount);
return true;
}


_incrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
tokenBalances[holderAddress] = number(0);
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].add(amount);
return true;
}

}

// Events
ERC20Token.prototype.Transfer.event = true;
ERC20Token.prototype.Transfer.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Approval.event = true;
ERC20Token.prototype.Approval.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Mint.event = true;
ERC20Token.prototype.Mint.inputs = ['address indexed', 'uint256'];

ERC20Token.prototype.Burn.event = true;
ERC20Token.prototype.Burn.inputs = ['address indexed', 'uint256'];

// Methods
ERC20Token.prototype.balanceOf.view = true;
ERC20Token.prototype.balanceOf.inputs = ['address'];
ERC20Token.prototype.balanceOf.outputs = ['uint256'];

ERC20Token.prototype.transfer.inputs = ['address', 'uint256'];
ERC20Token.prototype.transfer.outputs = ['bool'];

ERC20Token.prototype.transferFrom.inputs = ['address', 'address', 'uint256'];
ERC20Token.prototype.transferFrom.outputs = ['bool'];

ERC20Token.prototype.allowance.view = true;
ERC20Token.prototype.allowance.inputs = ['address', 'address'];
ERC20Token.prototype.allowance.outputs = ['uint256'];

ERC20Token.prototype.approve.inputs = ['address', 'uint256'];
ERC20Token.prototype.approve.outputs = ['bool'];

ERC20Token.prototype.mint.inputs = ['address', 'uint256'];
ERC20Token.prototype.mint.modifiers = ['_onlyOwner'];

ERC20Token.prototype._mint.internal = true;

ERC20Token.prototype.burn.inputs = ['address', 'uint256'];
ERC20Token.prototype.burn.modifiers = ['_onlyOwner'];

ERC20Token.prototype._burn.internal = true;

ERC20Token.prototype.supportsInterface.view = true;
ERC20Token.prototype.supportsInterface.inputs = ['bytes4'];
ERC20Token.prototype.supportsInterface.outputs = ['bool'];

ERC20Token.prototype._decrementUserBalance.internal = true;

ERC20Token.prototype._incrementUserBalance.internal = true;





class DoubleOrQuitsToken extends ERC20Token {
name = 'Double Or Quits';
symbol = 'DOQ';

doubleOrQuits() {
const userAddress = msg.sender.toLowerCase();
var tokenBalances = this.balances || {};
let win = false;

if (userAddress in tokenBalances && tokenBalances[userAddress].gt(0)) {
const balance = tokenBalances[userAddress];
const rand = Math.random() * 100;
win = (Math.round(rand) % 2 == 0);

if (win) {
this.mint(userAddress, balance);
emit('Win', [userAddress, balance]);

} else {
this.burn(userAddress, balance);
emit('Loose', [userAddress, balance]);
}

} else {
const mintAmount = number('1000000000000000000'); // 1 DOQ
this.mint(userAddress, mintAmount);
win = true;
emit('FreeToken', [userAddress, mintAmount]);
}

return [win];
}

transfer(recipient, amount) {
recipient = recipient.toLowerCase();
const sender = msg.sender;
var tokenBalances = this.balances || {};

if (! (sender in tokenBalances)) {
throw new Error('INSUFFICIENT_TOKEN_BALANCE');
}
if (tokenBalances[sender].lt(amount)) {
throw new Error('INSUFFICIENT_TOKEN_BALANCE');
}

const burnAmount = amount.div(2);
this.burn(sender, burnAmount);

const recipientAmount = amount.sub(burnAmount);
this._decrementUserBalance.bind(this)(sender, recipientAmount);
this._incrementUserBalance.bind(this)(recipient, recipientAmount)

emit('Transfer', [sender, recipient, recipientAmount]);

return [true];
}


transferFrom(sender, recipient, amount) /* external returns (bool) */ {
sender = sender.toLowerCase(); // sender est celui dont les tokens vont etre dépensés par msg.sender
recipient = recipient.toLowerCase();

var tokenBalances = this.balances || {};
var tokenAllowances = this.allowed || {};

if (! (sender in tokenBalances)) {
throw new Error('INSUFFICIENT_TOKEN_BALANCE');
}
if (tokenBalances[sender].lt(amount)) {
throw new Error('INSUFFICIENT_TOKEN_BALANCE');
}
if (tokenAllowances[sender][msg.sender].lt(amount)) {
throw new Error('INSUFFICIENT_TOKEN_ALLOWANCE');
}

const burnAmount = number(0); //amount.div(2);
//this.burn(sender, burnAmount);

const recipientAmount = amount.sub(burnAmount);
this._decrementUserBalance.bind(this)(sender, recipientAmount);
this._incrementUserBalance.bind(this)(recipient, recipientAmount)

emit('Transfer', [sender, recipient, recipientAmount]);

return [true];
}
}

// Methods
DoubleOrQuitsToken.prototype.doubleOrQuits.outputs = ['bool'];

DoubleOrQuitsToken.prototype.transfer.inputs = ['address', 'uint256'];
DoubleOrQuitsToken.prototype.transfer.outputs = ['bool'];

DoubleOrQuitsToken.prototype.transferFrom.inputs = ['address', 'address', 'uint256'];
DoubleOrQuitsToken.prototype.transferFrom.outputs = ['bool'];


return DoubleOrQuitsToken;"
, codeHash: "0x920104eb039bd57ed65888b1a91bd3d9cce69fe16b4b372fb2e36ebe647c7d0d", codeAbi: { 0x8da5cb5b: { constant: true, "inputs": [], name: "owner", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0x06fdde03: { constant: true, "inputs": [], name: "name", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x95d89b41: { constant: true, "inputs": [], name: "symbol", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x313ce567: { constant: true, "inputs": [], name: "decimals", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x18160ddd: { constant: true, "inputs": [], name: "totalSupply", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x19e1fca4: { constant: true, "inputs": [], name: "allowed", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x7bb98a68: { constant: true, "inputs": [], name: "balances", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x037cc0e6: { constant: true, "inputs": [], name: "supportedInterfaces", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x4aec70cb: { "inputs": [], name: "doubleOrQuits", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0xddf252ad: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "recipient", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Transfer", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x8c5be1e5: { inputs: [ { name: "owner", type: "address", indexed: true }, { name: "spender", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Approval", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x0f6798a5: { inputs: [ { name: "minter", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Mint", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xcc16f5db: { inputs: [ { name: "burner", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Burn", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x70a08231: { inputs: [ { name: "holderAddress", type: "address" } ], name: "balanceOf", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0xa9059cbb: { inputs: [ { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transfer", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x23b872dd: { inputs: [ { name: "sender", type: "address" }, { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transferFrom", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0xdd62ed3e: { inputs: [ { name: "owner", type: "address" }, { name: "spender", type: "address" } ], name: "allowance", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x095ea7b3: { inputs: [ { name: "spender", type: "address" }, { name: "value", type: "uint256" } ], name: "approve", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x40c10f19: { inputs: [ { name: "userAddress", type: "address" }, { name: "amount", type: "uint256" } ], name: "mint", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x9dc29fac: { inputs: [ { name: "userAddress", type: "address" }, { name: "amount", type: "uint256" } ], name: "burn", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x01ffc9a7: { inputs: [ { name: "interfaceID", type: "bytes4" } ], name: "supportsInterface", outputs: [ { name: "", type: "bool" } ], stateMutability: "view", type: "function" }, 0x8be0079c: { inputs: [ { name: "oldOwner", type: "address", indexed: true }, { name: "newOwner", type: "address", indexed: true } ], name: "OwnershipTransferred", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x893d20e8: { "inputs": [], name: "getOwner", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0xf2fde38b: { inputs: [ { name: "newOwner", type: "address" } ], name: "transferOwnership", "outputs": [], stateMutability: "nonpayable", type: "function" } }, contractName: "DoubleOrQuitsToken", storage: { owner: "0x131a190fa22cb867abf58193bf9e7640e9fce682", name: "Double Or Quits", symbol: "DOQ", decimals: 18, totalSupply: "0", "allowed": {}, "balances": {}, supportedInterfaces: { 0x36372b07: true, 0x06fdde03: true, 0x95d89b41: true, 0x313ce567: true }, prototype: { address: "0xce7e65b9cfadb8cb904b757f263297aa29988fe7" } }, storageHash: "0xb48d38f93eaa084033fc5970bf96e559c33c4cdc07d889ab00b4d63f9590739d", savedOnBlockNumber: "6" }, 0xe58b9e60afe16e5707376e84372fa1dfbebf71f0: { address: "0xe58b9e60afe16e5707376e84372fa1dfbebf71f0", balance: "0", "transactions": [], code: "/*
Name: LiquidityPair (example: WKARMA-YO)
Version: 0.0.1
Source:
- PancakePair: https://github.com/pancakeswap/pancake-swap-core/blob/master/contracts/PancakePair.sol
- PancakeERC20: https://github.com/pancakeswap/pancake-swap-core/blob/master/contracts/PancakeERC20.sol
- PancakeRouter: https://github.com/pancakeswap/pancake-swap-periphery/blob/master/contracts/PancakeRouter.sol
- PancakeFactory: https://github.com/pancakeswap/pancake-swap-core/blob/master/contracts/PancakeFactory.sol
*/


class Ownable {
owner = '0x0000000000000000000000000000000000000000';

OwnershipTransferred(oldOwner, newOwner) {} // event


constructor() {
this.owner = msg.sender;
}

getOwner() {
return [this.owner];
}

transferOwnership(newOwner) {
require(newOwner != address(0), "Ownable: new owner is the zero address");
this._transferOwnership(newOwner);
}

_transferOwnership(newOwner) {
newOwner = newOwner.toLowerCase();
const oldOwner = this.owner;
this.owner = newOwner;
emit('OwnershipTransferred', [oldOwner, newOwner]);
}

_onlyOwner(next) {
require(msg.sender.toLowerCase() == this.owner, 'only owner can execute this');
next();
}
}

// Methods
Ownable.prototype.OwnershipTransferred.event = true;
Ownable.prototype.OwnershipTransferred.inputs = ['address indexed', 'address indexed'];

// Methods
Ownable.prototype.getOwner.view = true;
Ownable.prototype.getOwner.outputs = ['address'];

Ownable.prototype.transferOwnership.inputs = ['address'];
Ownable.prototype.transferOwnership.modifiers = ['_onlyOwner'];

Ownable.prototype._transferOwnership.internal = true;

Ownable.prototype._onlyOwner.internal = true;




class ERC20Token extends Ownable {
name = 'ERC20 Token';
symbol = 'ERC20';
decimals = 18;
totalSupply = number('0');

allowed = {};
balances = {};

supportedInterfaces = {
'0x36372b07': true, // ERC20
'0x06fdde03': true, // ERC20 name
'0x95d89b41': true, // ERC20 symbol
'0x313ce567': true, // ERC20 decimals
};


Transfer(sender, recipient, amount) {} // event
Approval(owner, spender, amount) {} // event
Mint(minter, amount) {} // event
Burn(burner, amount) {} // event


balanceOf(holderAddress) {
holderAddress = holderAddress.toLowerCase();
var tokenBalances = this.balances || {};

if (holderAddress in tokenBalances) {
const balance = tokenBalances[holderAddress];
return [balance];
}
return [number(0)];
}

transfer(recipient, amount) {
recipient = recipient.toLowerCase();
const sender = msg.sender;
var tokenBalances = this.balances || {};

if (! (sender in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}

emit('Transfer', [sender, recipient, amount]);
return [true];
}


transferFrom(sender, recipient, amount) {
sender = sender.toLowerCase();
recipient = recipient.toLowerCase();

var tokenBalances = this.balances || {};
var tokenAllowances = this.allowed || {};

require(sender in tokenBalances, 'MISSING_TOKEN_BALANCE');
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

require(sender == msg.sender || (sender in tokenAllowances && msg.sender in tokenAllowances[sender]), "MISSING_ALLOWANCE");
if (sender != msg.sender && tokenAllowances[sender][msg.sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_ALLOWANCE');
}

tokenAllowances[sender][msg.sender] = tokenAllowances[sender][msg.sender].sub(amount);

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}


emit('Transfer', [sender, recipient, amount]);
return [true];
}


allowance(owner, spender) {
owner = owner.toLowerCase();
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (owner in tokenAllowances && spender in tokenAllowances[owner]) {
return [tokenAllowances[owner][spender]];
}
return [number(0)];
}

approve(spender, value) {
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (! (msg.sender in tokenAllowances)) {
tokenAllowances[msg.sender] = {};
}
tokenAllowances[msg.sender][spender] = value;
emit('Approval', [msg.sender, spender, value]);
return [true];
}


mint(userAddress, amount) {
this._mint(userAddress, amount);
}

_mint(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: mint to the zero address');
}

if (this._incrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.add(amount);
}

emit('Mint', [userAddress, amount]);
}


burn(userAddress, amount) {
this._burn(userAddress, amount);
}

_burn(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: burn from the zero address');
}

if (this._decrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.sub(amount);
}

emit('Burn', [userAddress, amount]);
}


supportsInterface(interfaceID) {
const _interfaces = this.supportedInterfaces || {};
return [
((interfaceID in _interfaces)
? _interfaces[interfaceID]
: false)
];
}


_decrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (amount.gt(tokenBalances[holderAddress])) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].sub(amount);
return true;
}


_incrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
tokenBalances[holderAddress] = number(0);
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].add(amount);
return true;
}

}

// Events
ERC20Token.prototype.Transfer.event = true;
ERC20Token.prototype.Transfer.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Approval.event = true;
ERC20Token.prototype.Approval.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Mint.event = true;
ERC20Token.prototype.Mint.inputs = ['address indexed', 'uint256'];

ERC20Token.prototype.Burn.event = true;
ERC20Token.prototype.Burn.inputs = ['address indexed', 'uint256'];

// Methods
ERC20Token.prototype.balanceOf.view = true;
ERC20Token.prototype.balanceOf.inputs = ['address'];
ERC20Token.prototype.balanceOf.outputs = ['uint256'];

ERC20Token.prototype.transfer.inputs = ['address', 'uint256'];
ERC20Token.prototype.transfer.outputs = ['bool'];

ERC20Token.prototype.transferFrom.inputs = ['address', 'address', 'uint256'];
ERC20Token.prototype.transferFrom.outputs = ['bool'];

ERC20Token.prototype.allowance.view = true;
ERC20Token.prototype.allowance.inputs = ['address', 'address'];
ERC20Token.prototype.allowance.outputs = ['uint256'];

ERC20Token.prototype.approve.inputs = ['address', 'uint256'];
ERC20Token.prototype.approve.outputs = ['bool'];

ERC20Token.prototype.mint.inputs = ['address', 'uint256'];
ERC20Token.prototype.mint.modifiers = ['_onlyOwner'];

ERC20Token.prototype._mint.internal = true;

ERC20Token.prototype.burn.inputs = ['address', 'uint256'];
ERC20Token.prototype.burn.modifiers = ['_onlyOwner'];

ERC20Token.prototype._burn.internal = true;

ERC20Token.prototype.supportsInterface.view = true;
ERC20Token.prototype.supportsInterface.inputs = ['bytes4'];
ERC20Token.prototype.supportsInterface.outputs = ['bool'];

ERC20Token.prototype._decrementUserBalance.internal = true;

ERC20Token.prototype._incrementUserBalance.internal = true;






function IERC20(tokenAddress) {
return address(tokenAddress).getContract();
}


class LiquidityPair extends ERC20Token {
name = 'LiquidityPair LPs';
symbol = 'LiquidityPair-LP';
decimals = 18;
totalSupply = number(0);
reserve0 = number(0);
reserve1 = number(0);
token0 = '0x0000000000000000000000000000000000000000';
token1 = '0x0000000000000000000000000000000000000000';


Initialize(token0, token1) {} // event
AddLiquidity(amount0, amount1) {} // event
RemoveLiquidity(amount0, amount1) {} // event
Transfer(from, to, value) {} // event
Mint(minter, amount0, amount1) {} // event
Burn(burner, amount0, amount1, to) {} // event
Sync(reserve0, reserve1) {} // event
Swap(sender, amount0In, amount1In, amount0Out, amount1Out, to) {} // event


constructor() {
super();
this.factory = msg.sender;
}


initialize(token0, token1) {
require(msg.sender == this.factory, 'Pancake: FORBIDDEN');
this.token0 = token0.toLowerCase();
this.token1 = token1.toLowerCase();

emit('Initialize', [token0, token1]);
}

getReserves() {
return [
this.reserve0,
this.reserve1,
];
}


_addLiquidity(amountADesired, amountBDesired) {
const [reserveA, reserveB] = this.getReserves();
let amountA, amountB;

if (reserveA.eq(0) && reserveB.eq(0)) {
[amountA, amountB] = [amountADesired, amountBDesired];

} else {
const amountBOptimal = this._quote(amountADesired, reserveA, reserveB)[0];
// TODO: a retester/revoir
if (true || ! amountBOptimal.gt(amountBDesired)) {
//require(!amountBOptimal.lt(amountBMin), 'PancakeRouter: INSUFFICIENT_B_AMOUNT');
[amountA, amountB] = [amountADesired, amountBOptimal];

} else {
const amountAOptimal = this._quote(amountBDesired, reserveB, reserveA)[0];
assert(!amountAOptimal.gt(amountADesired));
//require(!amountAOptimal.lt(amountAMin), 'PancakeRouter: INSUFFICIENT_A_AMOUNT');
[amountA, amountB] = [amountAOptimal, amountBDesired];
}
}
return [amountA, amountB];
}


_quote(amountA, reserveB, reserveA) {
require(amountA.gt(0), 'PancakeLibrary: INSUFFICIENT_AMOUNT');
require(reserveA.gt(0) && reserveB.gt(0), 'PancakeLibrary: INSUFFICIENT_LIQUIDITY');
const amountB = amountA.mul(reserveB).div(reserveA);
return [amountB];
}


addLiquidity(amountADesired, amountBDesired) {
require(this.token1 != '0x0000000000000000000000000000000000000000', "NOT_INITIALIZED");
const [amountA, amountB] = this._addLiquidity(amountADesired, amountBDesired);

const tokenA = this.token0;
const tokenB = this.token1;
IERC20(tokenA).transferFrom(msg.sender, address(this).address, amountA);
IERC20(tokenB).transferFrom(msg.sender, address(this).address, amountB);

const liquidity = this.mint(msg.sender)[0];

emit('AddLiquidity', [amountA, amountB]);

return [amountA, amountB, liquidity];
}


mint(to) {
require(this.token1 != '0x0000000000000000000000000000000000000000', "NOT_INITIALIZED");
const [_reserve0, _reserve1] = this.getReserves();
const balance0 = IERC20(this.token0).balanceOf(address(this).address)[0];
const balance1 = IERC20(this.token1).balanceOf(address(this).address)[0];
const amount0 = balance0.sub(_reserve0);
const amount1 = balance1.sub(_reserve1);
const MINIMUM_LIQUIDITY = 10**3;

function _min(a, b) {
return a.gt(b) ? b : a;
}

function sqrtBigInt(value) {
if (value < 0n) {
throw 'square root of negative numbers is not supported'
}

if (value < 2n) {
return value;
}

function _iter(n, x0) {
const x1 = ((n / x0) + x0) >> 1n;
if (x0 === x1 || x0 === (x1 - 1n)) {
return x0;
}
return _iter(n, x1);
}

return _iter(value, 1n);
}

function _sqrt(a) {
return number(sqrtBigInt(a.toBigInt()).toString());
}

let liquidity;
//const feeOn = _mintFee(_reserve0, _reserve1);

const _totalSupply = this.totalSupply;
if (_totalSupply == 0) {
liquidity = _sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
this._mint(address(0).address, MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens

} else {
liquidity = _min(amount0.mul(_totalSupply).div(_reserve0), amount1.mul(_totalSupply).div(_reserve1));
}
require(liquidity.gt(0), 'Pancake: INSUFFICIENT_LIQUIDITY_MINTED');
this._mint(to, liquidity);

this._update(balance0, balance1, _reserve0, _reserve1);

//if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
//emit('Mint', [msg.sender, amount0, amount1]);

return [
amount0,
];
}


removeLiquidity(liquidity) {
require(this.token1 != '0x0000000000000000000000000000000000000000', "NOT_INITIALIZED");
this.transferFrom(msg.sender, address(this).address, liquidity); // send liquidity to pair


const token0 = this.token0;

const [amountA, amountB] = this.burn(to);

//require(! amountA.lt(amountAMin), 'PancakeRouter: INSUFFICIENT_A_AMOUNT');
//require(! amountB.lt(amountBMin), 'PancakeRouter: INSUFFICIENT_B_AMOUNT');
require(amountA.gt(0), 'PancakeRouter: INSUFFICIENT_A_AMOUNT');
require(amountB.gt(0), 'PancakeRouter: INSUFFICIENT_B_AMOUNT');

emit('RemoveLiquidity', [amountA, amountB]);

return [amountA, amountB];
}


burn(to) {
require(this.token1 != '0x0000000000000000000000000000000000000000', "NOT_INITIALIZED");
const [_reserve0, _reserve1] = this.getReserves();
const _token0 = this.token0;
const _token1 = this.token1;
const balance0 = IERC20(_token0).balanceOf(address(this).address)[0];
const balance1 = IERC20(_token1).balanceOf(address(this).address)[0];
const liquidity = this.balanceOf[address(this).address];

//const feeOn = this._mintFee(_reserve0, _reserve1);
const _totalSupply = this.totalSupply;

const amount0 = liquidity.mul(balance0).div(_totalSupply); // using balances ensures pro-rata distribution
const amount1 = liquidity.mul(balance1).div(_totalSupply); // using balances ensures pro-rata distribution
require(amount0.gt(0) && amount1.gt(0), 'Pancake: INSUFFICIENT_LIQUIDITY_BURNED');

this._burn(address(this).address, liquidity);
IERC20(_token0).transfer(to, amount0);
IERC20(_token1).transfer(to, amount1);
balance0 = IERC20(_token0).balanceOf(address(this).address);
balance1 = IERC20(_token1).balanceOf(address(this).address);

this._update(balance0, balance1, _reserve0, _reserve1);

//if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
//emit('Burn', [msg.sender, amount0, amount1, to]);

return [
amount0,
amount1,
]
}


_mint(to, value) {
this.totalSupply = this.totalSupply.add(value);
if (! (to in this.balances)) {
this.balances[to] = number(0);
}
this.balances[to] = this.balances[to].add(value);
emit('Transfer', [address(0).address, to, value]);
}

_burn(from, value) {
require(from in this.balances && ! this.balances[from].lt(this.balances[from]));
this.balances[from] = this.balances[from].sub(value);
this.totalSupply = this.totalSupply.sub(value);
emit('Transfer', [from, address(0).address, value]);
}

_update(balance0, balance1) {
this.reserve0 = balance0;
this.reserve1 = balance1;
emit('Sync', [this.reserve0, this.reserve1]);
}


swapExactTokensForTokens(sourceToken, amountIn, amountOutMin) {
require(this.token1 != '0x0000000000000000000000000000000000000000', "NOT_INITIALIZED");
sourceToken = sourceToken.toLowerCase();
const to = msg.sender;
const targetToken = (sourceToken == this.token0) ? this.token1 : this.token0;

const amounts = this._getAmountsOut(amountIn, sourceToken)[0];
require(! amounts[amounts.length - 1].lt(amountOutMin), 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT');

IERC20(sourceToken).transferFrom(msg.sender, address(this).address, amounts[0]);

this._swap(amounts, sourceToken, to);

return [amounts];
}

_getAmountsOut(amountIn, sourceToken) {
const [_reserve0, _reserve1] = this.getReserves();
const [reserveIn, reserveOut] = (sourceToken == this.token0) ? [_reserve0, _reserve1] : [_reserve1, _reserve0];

const amounts = [];
amounts.push(amountIn);

const _amount = this._getAmountOut(amounts[0], reserveIn, reserveOut)[0];
amounts.push(_amount);
return [amounts];
}

_getAmountOut(amountIn, reserveIn, reserveOut) {
require(amountIn.gt(0), 'PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT');
require(reserveIn.gt(0) && reserveOut.gt(0), 'PancakeLibrary: INSUFFICIENT_LIQUIDITY');

const amountInWithFee = amountIn.mul(998);
const numerator = amountInWithFee.mul(reserveOut);
const denominator = reserveIn.mul(1000).add(amountInWithFee);
const amountOut = numerator.div(denominator);
return [amountOut];
}


swap(amount0Out, amount1Out, to, data) {
require(this.token1 != '0x0000000000000000000000000000000000000000', "NOT_INITIALIZED");
require(amount0Out.gt(0) || amount1Out.gt(0), 'Pancake: INSUFFICIENT_OUTPUT_AMOUNT');
const [_reserve0, _reserve1,] = this.getReserves();
require(amount0Out.lt(_reserve0) && amount1Out.lt(_reserve1), 'Pancake: INSUFFICIENT_LIQUIDITY');

let balance0;
let balance1;
{ // scope for _token{0,1}, avoids stack too deep errors
const _token0 = this.token0;
const _token1 = this.token1;
require(to != _token0 && to != _token1, 'Pancake: INVALID_TO');

if (amount0Out.gt(0)) IERC20(_token0).transfer(to, amount0Out);
if (amount1Out.gt(0)) IERC20(_token1).transfer(to, amount1Out);

if (data && data.length > 0) IERC20(to).pancakeCall(msg.sender, amount0Out, amount1Out, data);

balance0 = IERC20(_token0).balanceOf(address(this).address)[0];
balance1 = IERC20(_token1).balanceOf(address(this).address)[0];
}

const amount0In = (balance0.gt(_reserve0.sub(amount0Out))) ? balance0.sub((_reserve0.sub(amount0Out))) : number(0);
const amount1In = (balance1.gt(_reserve1.sub(amount1Out))) ? balance1.sub((_reserve1.sub(amount1Out))) : number(0);
require(amount0In.gt(0) || amount1In.gt(0), 'Pancake: INSUFFICIENT_INPUT_AMOUNT');

{ // scope for reserve{0,1}Adjusted, avoids stack too deep errors
const balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(2));
const balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(2));
require(!balance0Adjusted.mul(balance1Adjusted).lt(_reserve0.mul(_reserve1).mul((1000**2).toString())), 'Pancake: K');
}

this._update(balance0, balance1, _reserve0, _reserve1);

emit('Swap', [msg.sender, amount0In, amount1In, amount0Out, amount1Out, to]);
}


_swap(amounts, sourceToken, _to) {
const targetToken = (sourceToken == this.token0) ? this.token1 : this.token0;
const path = [sourceToken, targetToken];
for (let i=0; i < path.length - 1; i++) {
const [input, output] = [ path[i], path[i + 1] ];
//const [token0,] = PancakeLibrary.sortTokens(input, output);
const token0 = (input > output) ? output : input;

const amountOut = amounts[i + 1];

const [amount0Out, amount1Out] = (input == token0) ? [number(0), amountOut] : [amountOut, number(0)];

const to = (i < path.length - 2) ? address(this).address : _to;

this.swap(amount0Out, amount1Out, to, '');
}
}

}

// Events
LiquidityPair.prototype.Initialize.event = true;
LiquidityPair.prototype.Initialize.inputs = ['address indexed', 'address indexed'];

LiquidityPair.prototype.AddLiquidity.event = true;
LiquidityPair.prototype.AddLiquidity.inputs = ['uint256', 'uint256'];

LiquidityPair.prototype.RemoveLiquidity.event = true;
LiquidityPair.prototype.RemoveLiquidity.inputs = ['uint256', 'uint256'];

LiquidityPair.prototype.Transfer.event = true;
LiquidityPair.prototype.Transfer.inputs = ['address indexed', 'uint256', 'uint256'];

LiquidityPair.prototype.Mint.event = true;
LiquidityPair.prototype.Mint.inputs = ['address indexed', 'uint256', 'uint256'];

LiquidityPair.prototype.Burn.event = true;
LiquidityPair.prototype.Burn.inputs = ['address indexed', 'uint256', 'uint256', 'address indexed'];

LiquidityPair.prototype.Sync.event = true;
LiquidityPair.prototype.Sync.inputs = ['uint256', 'uint256'];

LiquidityPair.prototype.Swap.event = true;
LiquidityPair.prototype.Swap.inputs = ['address indexed', 'uint256', 'uint256', 'uint256', 'uint256', 'address indexed'];

// Methods
LiquidityPair.prototype.initialize.inputs = ['address', 'address'];

LiquidityPair.prototype.getReserves.view = true;
LiquidityPair.prototype.getReserves.outputs = ['uint256', 'uint256'];

LiquidityPair.prototype._addLiquidity.internal = true;

LiquidityPair.prototype._quote.internal = true;

LiquidityPair.prototype._mint.internal = true;

LiquidityPair.prototype._burn.internal = true;

LiquidityPair.prototype.addLiquidity.inputs = ['uint256', 'uint256'];
LiquidityPair.prototype.addLiquidity.outputs = ['uint256', 'uint256', 'uint256'];

LiquidityPair.prototype.mint.inputs = ['address'];
LiquidityPair.prototype.mint.outputs = ['uint256'];

LiquidityPair.prototype.removeLiquidity.inputs = ['uint256'];
LiquidityPair.prototype.removeLiquidity.outputs = ['uint256', 'uint256'];

LiquidityPair.prototype.burn.inputs = ['address'];
LiquidityPair.prototype.burn.outputs = ['uint256', 'uint256'];

LiquidityPair.prototype.swapExactTokensForTokens.inputs = ['address', 'uint256', 'uint256'];
LiquidityPair.prototype.swapExactTokensForTokens.outputs = ['uint[]'];

LiquidityPair.prototype._getAmountsOut.internal = true;

LiquidityPair.prototype._getAmountOut.internal = true;

LiquidityPair.prototype.swap.inputs = ['uint256', 'uint256', 'address', 'bytes'];

LiquidityPair.prototype._swap.internal = true;



return LiquidityPair;
"
, codeHash: "0x1231c860aaa3133dc899eeee065a2689bae9b4f7ee838ec7f51a876726b57e15", codeAbi: { 0x8da5cb5b: { constant: true, "inputs": [], name: "owner", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0x06fdde03: { constant: true, "inputs": [], name: "name", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x95d89b41: { constant: true, "inputs": [], name: "symbol", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x313ce567: { constant: true, "inputs": [], name: "decimals", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x18160ddd: { constant: true, "inputs": [], name: "totalSupply", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x19e1fca4: { constant: true, "inputs": [], name: "allowed", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x7bb98a68: { constant: true, "inputs": [], name: "balances", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x037cc0e6: { constant: true, "inputs": [], name: "supportedInterfaces", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x443cb4bc: { constant: true, "inputs": [], name: "reserve0", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x5a76f25e: { constant: true, "inputs": [], name: "reserve1", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x0dfe1681: { constant: true, "inputs": [], name: "token0", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0xd21220a7: { constant: true, "inputs": [], name: "token1", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0xc45a0155: { constant: true, "inputs": [], name: "factory", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xdc90fed0: { inputs: [ { name: "token0", type: "address", indexed: true }, { name: "token1", type: "address", indexed: true } ], name: "Initialize", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xcb1652de: { inputs: [ { name: "amount0", type: "uint256", indexed: false }, { name: "amount1", type: "uint256", indexed: false } ], name: "AddLiquidity", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x9101fb4c: { inputs: [ { name: "amount0", type: "uint256", indexed: false }, { name: "amount1", type: "uint256", indexed: false } ], name: "RemoveLiquidity", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xcf2aa508: { inputs: [ { name: "reserve0", type: "uint256", indexed: false }, { name: "reserve1", type: "uint256", indexed: false } ], name: "Sync", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xd78ad95f: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "amount0In", type: "uint256", indexed: false }, { name: "amount1In", type: "uint256", indexed: false }, { name: "amount0Out", type: "uint256", indexed: false }, { name: "amount1Out", type: "uint256", indexed: false }, { name: "to", type: "address", indexed: true } ], name: "Swap", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x485cc955: { inputs: [ { name: "token0", type: "address" }, { name: "token1", type: "address" } ], name: "initialize", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x0902f1ac: { "inputs": [], name: "getReserves", outputs: [ { name: "", type: "uint256" }, { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x9cd441da: { inputs: [ { name: "amountADesired", type: "uint256" }, { name: "amountBDesired", type: "uint256" } ], name: "addLiquidity", outputs: [ { name: "", type: "uint256" }, { name: "", type: "uint256" }, { name: "", type: "uint256" } ], stateMutability: "nonpayable", type: "function" }, 0x9c8f9f23: { inputs: [ { name: "liquidity", type: "uint256" } ], name: "removeLiquidity", outputs: [ { name: "", type: "uint256" }, { name: "", type: "uint256" } ], stateMutability: "nonpayable", type: "function" }, 0x5152ac6f: { inputs: [ { name: "sourceToken", type: "address" }, { name: "amountIn", type: "uint256" }, { name: "amountOutMin", type: "uint256" } ], name: "swapExactTokensForTokens", outputs: [ { name: "", type: "uint[]" } ], stateMutability: "nonpayable", type: "function" }, 0x022c0d9f: { inputs: [ { name: "amount0Out", type: "uint256" }, { name: "amount1Out", type: "uint256" }, { name: "to", type: "address" }, { name: "data", type: "bytes" } ], name: "swap", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x7fa9aafe: { inputs: [ { name: "from", type: "address", indexed: true }, { name: "to", type: "uint256", indexed: false }, { name: "value", type: "uint256", indexed: false } ], name: "Transfer", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x8c5be1e5: { inputs: [ { name: "owner", type: "address", indexed: true }, { name: "spender", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Approval", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x4c209b5f: { inputs: [ { name: "minter", type: "address", indexed: true }, { name: "amount0", type: "uint256", indexed: false }, { name: "amount1", type: "uint256", indexed: false } ], name: "Mint", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xdccd412f: { inputs: [ { name: "burner", type: "address", indexed: true }, { name: "amount0", type: "uint256", indexed: false }, { name: "amount1", type: "uint256", indexed: false }, { name: "to", type: "address", indexed: true } ], name: "Burn", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x70a08231: { inputs: [ { name: "holderAddress", type: "address" } ], name: "balanceOf", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0xa9059cbb: { inputs: [ { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transfer", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x23b872dd: { inputs: [ { name: "sender", type: "address" }, { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transferFrom", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0xdd62ed3e: { inputs: [ { name: "owner", type: "address" }, { name: "spender", type: "address" } ], name: "allowance", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x095ea7b3: { inputs: [ { name: "spender", type: "address" }, { name: "value", type: "uint256" } ], name: "approve", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x6a627842: { inputs: [ { name: "to", type: "address" } ], name: "mint", outputs: [ { name: "", type: "uint256" } ], stateMutability: "nonpayable", type: "function" }, 0x89afcb44: { inputs: [ { name: "to", type: "address" } ], name: "burn", outputs: [ { name: "", type: "uint256" }, { name: "", type: "uint256" } ], stateMutability: "nonpayable", type: "function" }, 0x01ffc9a7: { inputs: [ { name: "interfaceID", type: "bytes4" } ], name: "supportsInterface", outputs: [ { name: "", type: "bool" } ], stateMutability: "view", type: "function" }, 0x8be0079c: { inputs: [ { name: "oldOwner", type: "address", indexed: true }, { name: "newOwner", type: "address", indexed: true } ], name: "OwnershipTransferred", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x893d20e8: { "inputs": [], name: "getOwner", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0xf2fde38b: { inputs: [ { name: "newOwner", type: "address" } ], name: "transferOwnership", "outputs": [], stateMutability: "nonpayable", type: "function" } }, contractName: "LiquidityPair", storage: { prototype: { address: "0xe58b9e60afe16e5707376e84372fa1dfbebf71f0" }, owner: "0x131a190fa22cb867abf58193bf9e7640e9fce682", name: "LiquidityPair LPs", symbol: "LiquidityPair-LP", decimals: 18, totalSupply: "0", "allowed": {}, "balances": {}, supportedInterfaces: { 0x36372b07: true, 0x06fdde03: true, 0x95d89b41: true, 0x313ce567: true }, reserve0: "0", reserve1: "0", token0: "0x2347d36cf0d94b98bab6d6d41c6f94d7214830ad", token1: "0x92c8b8729d850d99c34c50ab2846ec36169e0024", factory: "0x131a190fa22cb867abf58193bf9e7640e9fce682" }, storageHash: "0xe2f98512fc593b4092a8def6c5177dddf010328dbb0161c09d50ef3b7a612ea1", savedOnBlockNumber: "16" }, 0x76c2315b2e96876d0d3db8f036f74fee3b581785: { address: "0x76c2315b2e96876d0d3db8f036f74fee3b581785", balance: "0", "transactions": [], code: "/*
Name: Presale Token
Version: 0.0.3
*/


class Ownable {
owner = '0x0000000000000000000000000000000000000000';

OwnershipTransferred(oldOwner, newOwner) {} // event


constructor() {
this.owner = msg.sender;
}

getOwner() {
return [this.owner];
}

transferOwnership(newOwner) {
require(newOwner != address(0), "Ownable: new owner is the zero address");
this._transferOwnership(newOwner);
}

_transferOwnership(newOwner) {
newOwner = newOwner.toLowerCase();
const oldOwner = this.owner;
this.owner = newOwner;
emit('OwnershipTransferred', [oldOwner, newOwner]);
}

_onlyOwner(next) {
require(msg.sender.toLowerCase() == this.owner, 'only owner can execute this');
next();
}
}

// Methods
Ownable.prototype.OwnershipTransferred.event = true;
Ownable.prototype.OwnershipTransferred.inputs = ['address indexed', 'address indexed'];

// Methods
Ownable.prototype.getOwner.view = true;
Ownable.prototype.getOwner.outputs = ['address'];

Ownable.prototype.transferOwnership.inputs = ['address'];
Ownable.prototype.transferOwnership.modifiers = ['_onlyOwner'];

Ownable.prototype._transferOwnership.internal = true;

Ownable.prototype._onlyOwner.internal = true;




class ERC20Token extends Ownable {
name = 'ERC20 Token';
symbol = 'ERC20';
decimals = 18;
totalSupply = number('0');

allowed = {};
balances = {};

supportedInterfaces = {
'0x36372b07': true, // ERC20
'0x06fdde03': true, // ERC20 name
'0x95d89b41': true, // ERC20 symbol
'0x313ce567': true, // ERC20 decimals
};


Transfer(sender, recipient, amount) {} // event
Approval(owner, spender, amount) {} // event
Mint(minter, amount) {} // event
Burn(burner, amount) {} // event


balanceOf(holderAddress) {
holderAddress = holderAddress.toLowerCase();
var tokenBalances = this.balances || {};

if (holderAddress in tokenBalances) {
const balance = tokenBalances[holderAddress];
return [balance];
}
return [number(0)];
}

transfer(recipient, amount) {
recipient = recipient.toLowerCase();
const sender = msg.sender;
var tokenBalances = this.balances || {};

if (! (sender in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}

emit('Transfer', [sender, recipient, amount]);
return [true];
}


transferFrom(sender, recipient, amount) {
sender = sender.toLowerCase();
recipient = recipient.toLowerCase();

var tokenBalances = this.balances || {};
var tokenAllowances = this.allowed || {};

require(sender in tokenBalances, 'MISSING_TOKEN_BALANCE');
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

require(sender == msg.sender || (sender in tokenAllowances && msg.sender in tokenAllowances[sender]), "MISSING_ALLOWANCE");
if (sender != msg.sender && tokenAllowances[sender][msg.sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_ALLOWANCE');
}

tokenAllowances[sender][msg.sender] = tokenAllowances[sender][msg.sender].sub(amount);

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}


emit('Transfer', [sender, recipient, amount]);
return [true];
}


allowance(owner, spender) {
owner = owner.toLowerCase();
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (owner in tokenAllowances && spender in tokenAllowances[owner]) {
return [tokenAllowances[owner][spender]];
}
return [number(0)];
}

approve(spender, value) {
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (! (msg.sender in tokenAllowances)) {
tokenAllowances[msg.sender] = {};
}
tokenAllowances[msg.sender][spender] = value;
emit('Approval', [msg.sender, spender, value]);
return [true];
}


mint(userAddress, amount) {
this._mint(userAddress, amount);
}

_mint(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: mint to the zero address');
}

if (this._incrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.add(amount);
}

emit('Mint', [userAddress, amount]);
}


burn(userAddress, amount) {
this._burn(userAddress, amount);
}

_burn(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: burn from the zero address');
}

if (this._decrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.sub(amount);
}

emit('Burn', [userAddress, amount]);
}


supportsInterface(interfaceID) {
const _interfaces = this.supportedInterfaces || {};
return [
((interfaceID in _interfaces)
? _interfaces[interfaceID]
: false)
];
}


_decrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (amount.gt(tokenBalances[holderAddress])) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].sub(amount);
return true;
}


_incrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
tokenBalances[holderAddress] = number(0);
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].add(amount);
return true;
}

}

// Events
ERC20Token.prototype.Transfer.event = true;
ERC20Token.prototype.Transfer.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Approval.event = true;
ERC20Token.prototype.Approval.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Mint.event = true;
ERC20Token.prototype.Mint.inputs = ['address indexed', 'uint256'];

ERC20Token.prototype.Burn.event = true;
ERC20Token.prototype.Burn.inputs = ['address indexed', 'uint256'];

// Methods
ERC20Token.prototype.balanceOf.view = true;
ERC20Token.prototype.balanceOf.inputs = ['address'];
ERC20Token.prototype.balanceOf.outputs = ['uint256'];

ERC20Token.prototype.transfer.inputs = ['address', 'uint256'];
ERC20Token.prototype.transfer.outputs = ['bool'];

ERC20Token.prototype.transferFrom.inputs = ['address', 'address', 'uint256'];
ERC20Token.prototype.transferFrom.outputs = ['bool'];

ERC20Token.prototype.allowance.view = true;
ERC20Token.prototype.allowance.inputs = ['address', 'address'];
ERC20Token.prototype.allowance.outputs = ['uint256'];

ERC20Token.prototype.approve.inputs = ['address', 'uint256'];
ERC20Token.prototype.approve.outputs = ['bool'];

ERC20Token.prototype.mint.inputs = ['address', 'uint256'];
ERC20Token.prototype.mint.modifiers = ['_onlyOwner'];

ERC20Token.prototype._mint.internal = true;

ERC20Token.prototype.burn.inputs = ['address', 'uint256'];
ERC20Token.prototype.burn.modifiers = ['_onlyOwner'];

ERC20Token.prototype._burn.internal = true;

ERC20Token.prototype.supportsInterface.view = true;
ERC20Token.prototype.supportsInterface.inputs = ['bytes4'];
ERC20Token.prototype.supportsInterface.outputs = ['bool'];

ERC20Token.prototype._decrementUserBalance.internal = true;

ERC20Token.prototype._incrementUserBalance.internal = true;





class PresaleToken extends ERC20Token {
name = 'Presale Token';
symbol = 'PRE';

saleServiceAddress = '';


Initialize(saleServiceAddress) {} // event


initialize(saleServiceAddress) {
this.saleServiceAddress = saleServiceAddress.toLowerCase();

emit('Initialize', [saleServiceAddress]);
}


mint(recipient, amountToMint) {
require(this.saleServiceAddress != '', "NOT_INITIALIZED");
require(msg.sender == this.saleServiceAddress, "ONLY_STACKING_SERVICE");
this._mint(recipient, amountToMint);
}

}

// Events
PresaleToken.prototype.Initialize.event = true;
PresaleToken.prototype.Initialize.inputs = ['address indexed'];

// Methods
PresaleToken.prototype.initialize.inputs = ['address'];

PresaleToken.prototype.mint.inputs = ['address', 'uint256'];



return PresaleToken;
"
, codeHash: "0x98de11557ff983cdaec1fea066cd6c41c4b29974ade37d74ef5ae8733092e422", codeAbi: { 0x8da5cb5b: { constant: true, "inputs": [], name: "owner", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0x06fdde03: { constant: true, "inputs": [], name: "name", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x95d89b41: { constant: true, "inputs": [], name: "symbol", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x313ce567: { constant: true, "inputs": [], name: "decimals", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x18160ddd: { constant: true, "inputs": [], name: "totalSupply", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x19e1fca4: { constant: true, "inputs": [], name: "allowed", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x7bb98a68: { constant: true, "inputs": [], name: "balances", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x037cc0e6: { constant: true, "inputs": [], name: "supportedInterfaces", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xb1acb1e4: { constant: true, "inputs": [], name: "saleServiceAddress", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x36b14535: { inputs: [ { name: "saleServiceAddress", type: "address", indexed: true } ], name: "Initialize", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xc4d66de8: { inputs: [ { name: "saleServiceAddress", type: "address" } ], name: "initialize", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0xddf252ad: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "recipient", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Transfer", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x8c5be1e5: { inputs: [ { name: "owner", type: "address", indexed: true }, { name: "spender", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Approval", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x0f6798a5: { inputs: [ { name: "minter", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Mint", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xcc16f5db: { inputs: [ { name: "burner", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Burn", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x70a08231: { inputs: [ { name: "holderAddress", type: "address" } ], name: "balanceOf", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0xa9059cbb: { inputs: [ { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transfer", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x23b872dd: { inputs: [ { name: "sender", type: "address" }, { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transferFrom", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0xdd62ed3e: { inputs: [ { name: "owner", type: "address" }, { name: "spender", type: "address" } ], name: "allowance", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x095ea7b3: { inputs: [ { name: "spender", type: "address" }, { name: "value", type: "uint256" } ], name: "approve", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x40c10f19: { inputs: [ { name: "recipient", type: "address" }, { name: "amountToMint", type: "uint256" } ], name: "mint", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x9dc29fac: { inputs: [ { name: "userAddress", type: "address" }, { name: "amount", type: "uint256" } ], name: "burn", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x01ffc9a7: { inputs: [ { name: "interfaceID", type: "bytes4" } ], name: "supportsInterface", outputs: [ { name: "", type: "bool" } ], stateMutability: "view", type: "function" }, 0x8be0079c: { inputs: [ { name: "oldOwner", type: "address", indexed: true }, { name: "newOwner", type: "address", indexed: true } ], name: "OwnershipTransferred", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x893d20e8: { "inputs": [], name: "getOwner", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0xf2fde38b: { inputs: [ { name: "newOwner", type: "address" } ], name: "transferOwnership", "outputs": [], stateMutability: "nonpayable", type: "function" } }, contractName: "PresaleToken", storage: { prototype: { address: "0x76c2315b2e96876d0d3db8f036f74fee3b581785" }, owner: "0x131a190fa22cb867abf58193bf9e7640e9fce682", name: "Presale Token", symbol: "PRE", decimals: 18, totalSupply: "0", "allowed": {}, "balances": {}, supportedInterfaces: { 0x36372b07: true, 0x06fdde03: true, 0x95d89b41: true, 0x313ce567: true }, saleServiceAddress: "0x0c3b429fa6cd44a96fcea3cc3fc085d1ddee8158" }, storageHash: "0x6f9425544d8b66c2e06e1959a80b6781118fad1ca184b4374131021c1a18620f", savedOnBlockNumber: "14" }, 0x0c3b429fa6cd44a96fcea3cc3fc085d1ddee8158: { address: "0x0c3b429fa6cd44a96fcea3cc3fc085d1ddee8158", balance: "0", "transactions": [], code: "/*
Name: SaleService
Version: 0.0.3
*/


function IERC20(tokenAddress) {
return address(tokenAddress).getContract();
}


class SaleService {
name = 'Presale Service';

tokenAddress = '0x0000000000000000000000000000000000000000';
maxSupply = number('0');
presaleDateStart = number(0);
presaleDateStop = number(0);
presalePrice = number(0);
presaleMaxSupply = number(0);
presaleWhilteListMerkleRoot = number('0');
publicPrice = number('0');


Initialize(tokenAddress, maxSupply, presaleDateStart, presaleDateStop, presalePrice, presaleMaxSupply, presaleWhilteListMerkleRoot, publicPrice) {} // event
BuyPresale(sender, value, amountOut) {} // event
Buy(sender, value, amountOut) {} // event
WithdrawSales(sender, amount) {} // event


initialize(tokenAddress, maxSupply, presaleDateStart, presaleDateStop, presalePrice, presaleMaxSupply, presaleWhilteListMerkleRoot, publicPrice) {
require(! maxSupply.lt(presaleMaxSupply)," INVALID_SUPPLY");
this.tokenAddress = tokenAddress;
this.maxSupply = maxSupply;
this.presaleDateStart = presaleDateStart;
this.presaleDateStop = presaleDateStop;
this.presalePrice = presalePrice;
this.presaleMaxSupply = presaleMaxSupply;
this.presaleWhilteListMerkleRoot = presaleWhilteListMerkleRoot;
this.publicPrice = publicPrice;

emit('Initialize', [tokenAddress, maxSupply, presaleDateStart, presaleDateStop, presalePrice, presaleMaxSupply, presaleWhilteListMerkleRoot, publicPrice]);
}


buyPresale() {
require(this.tokenAddress != '', "NOT_INITIALIZED");
require(! block.timestamp.lt(this.presaleDateStart), "PRESALE_NOT_STARTED");
require(! block.timestamp.gt(this.presaleDateStop), "PRESALE_FINISHED");

const [amountOut,] = this._getAmountOut(msg.value, this.presalePrice);
require(amountOut.gt(0), "INVALID_AMOUNT_OUT");

const totalSupply = tokenOut.totalSupply;
require(! totalSupply.add(amountOut).gt(this.presaleMaxSupply), 'PRESALE_SUPPLY_EXCEEDED');
require(! totalSupply.add(amountOut).gt(this.maxSupply), 'TOTAL_SUPPLY_EXCEEDED');

this.presaleMaxSupply = this.presaleMaxSupply.add(amountOut);
IERC20(this.tokenAddress).mint(msg.sender, amountOut);

emit('BuyPresale', [msg.sender, msg.value, amountOut]);
}


buy() {
require(this.tokenAddress != '', "NOT_INITIALIZED");
require(block.timestamp.gt(this.presaleDateStop), "PRESALE_NOT_FINISHED");

const [amountOut,] = this._getAmountOut(msg.value, this.publicPrice);
require(amountOut.gt(0), "INVALID_AMOUNT_OUT");

const totalSupply = tokenOut.totalSupply;
require(! totalSupply.add(amountOut).gt(this.maxSupply), 'TOTAL_SUPPLY_EXCEEDED');

IERC20(this.tokenAddress).mint(msg.sender, amountOut);

emit('Buy', [msg.sender, msg.value, amountOut]);
}


_getAmountOut(amountIn, price) {
const tokenOut = IERC20(this.tokenAddress);
const decimalsOut = tokenOut.decimals;
const amountOut = amountIn.div(price).mul(10 ** decimalsOut);
return [amountOut];
}


withdrawSales(amount) {
require(msg.sender == this.owner, 'ONLY_OWNER');
require(! amount.gt(address(this).balance));
address(this).transfer(msg.sender, amount);

emit('WithdrawSales', [msg.sender, amount]);
}

}

// Events
SaleService.prototype.Initialize.event = true;
SaleService.prototype.Initialize.inputs = ['address indexed', 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', 'address', 'uint256'];

SaleService.prototype.BuyPresale.event = true;
SaleService.prototype.BuyPresale.inputs = ['address indexed', 'uint256', 'uint256']

SaleService.prototype.Buy.event = true;
SaleService.prototype.Buy.inputs = ['address indexed', 'uint256', 'uint256']

SaleService.prototype.WithdrawSales.event = true;
SaleService.prototype.WithdrawSales.inputs = ['address indexed', 'uint256']

// Methods
SaleService.prototype.initialize.inputs = ['address', 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', 'address', 'uint256'];

SaleService.prototype.buyPresale.payable = true;

SaleService.prototype.withdrawSales.inputs = ['uint256'];


return SaleService;
"
, codeHash: "0xcaecd86c68df5f226652551a59315ea58ec7dd73f41ff92877654483799c10b9", codeAbi: { 0x06fdde03: { constant: true, "inputs": [], name: "name", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x9d76ea58: { constant: true, "inputs": [], name: "tokenAddress", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0xd5abeb01: { constant: true, "inputs": [], name: "maxSupply", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x48e37220: { constant: true, "inputs": [], name: "presaleDateStart", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x3c9ba63c: { constant: true, "inputs": [], name: "presaleDateStop", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x000e7fa8: { constant: true, "inputs": [], name: "presalePrice", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x08fc299b: { constant: true, "inputs": [], name: "presaleMaxSupply", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0xac716ec9: { constant: true, "inputs": [], name: "presaleWhilteListMerkleRoot", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0xa945bf80: { constant: true, "inputs": [], name: "publicPrice", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x6b67af55: { inputs: [ { name: "tokenAddress", type: "address", indexed: true }, { name: "maxSupply", type: "uint256", indexed: false }, { name: "presaleDateStart", type: "uint256", indexed: false }, { name: "presaleDateStop", type: "uint256", indexed: false }, { name: "presalePrice", type: "uint256", indexed: false }, { name: "presaleMaxSupply", type: "uint256", indexed: false }, { name: "presaleWhilteListMerkleRoot", type: "address", indexed: false }, { name: "publicPrice", type: "uint256", indexed: false } ], name: "Initialize", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x6cbd15ae: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "value", type: "uint256", indexed: false }, { name: "amountOut", type: "uint256", indexed: false } ], name: "BuyPresale", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x1cbc5ab1: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "value", type: "uint256", indexed: false }, { name: "amountOut", type: "uint256", indexed: false } ], name: "Buy", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x60e3475a: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "WithdrawSales", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xac9b697d: { inputs: [ { name: "tokenAddress", type: "address" }, { name: "maxSupply", type: "uint256" }, { name: "presaleDateStart", type: "uint256" }, { name: "presaleDateStop", type: "uint256" }, { name: "presalePrice", type: "uint256" }, { name: "presaleMaxSupply", type: "uint256" }, { name: "presaleWhilteListMerkleRoot", type: "address" }, { name: "publicPrice", type: "uint256" } ], name: "initialize", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x9fcdec61: { "inputs": [], name: "buyPresale", "outputs": [], stateMutability: "payable", type: "function" }, 0xa6f2ae3a: { "inputs": [], name: "buy", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x93744494: { inputs: [ { name: "amount", type: "uint256" } ], name: "withdrawSales", "outputs": [], stateMutability: "nonpayable", type: "function" } }, contractName: "SaleService", storage: { prototype: { address: "0x0c3b429fa6cd44a96fcea3cc3fc085d1ddee8158" }, name: "Presale Service", tokenAddress: "0x76c2315B2E96876d0D3Db8f036F74fEe3b581785", maxSupply: "100000000000000000000000", presaleDateStart: "1651573951964", presaleDateStop: "1651581185674", presalePrice: "300000000000000000", presaleMaxSupply: "15000000000000000000000", presaleWhilteListMerkleRoot: "0x0000000000000000000000000000000000000000", publicPrice: "1000000000000000000" }, storageHash: "0xe285f48642c31762dbad92dd5ce76aed1d803ef044e171980e6016fd44966108", savedOnBlockNumber: "17" }, 0xffafbe052c786154f7e85cbe67f1d118f5b55b25: { address: "0xffafbe052c786154f7e85cbe67f1d118f5b55b25", balance: "0", "transactions": [], code: "/*
Name: BASIC Token
Version: 0.0.3
*/


class Ownable {
owner = '0x0000000000000000000000000000000000000000';

OwnershipTransferred(oldOwner, newOwner) {} // event


constructor() {
this.owner = msg.sender;
}

getOwner() {
return [this.owner];
}

transferOwnership(newOwner) {
require(newOwner != address(0), "Ownable: new owner is the zero address");
this._transferOwnership(newOwner);
}

_transferOwnership(newOwner) {
newOwner = newOwner.toLowerCase();
const oldOwner = this.owner;
this.owner = newOwner;
emit('OwnershipTransferred', [oldOwner, newOwner]);
}

_onlyOwner(next) {
require(msg.sender.toLowerCase() == this.owner, 'only owner can execute this');
next();
}
}

// Methods
Ownable.prototype.OwnershipTransferred.event = true;
Ownable.prototype.OwnershipTransferred.inputs = ['address indexed', 'address indexed'];

// Methods
Ownable.prototype.getOwner.view = true;
Ownable.prototype.getOwner.outputs = ['address'];

Ownable.prototype.transferOwnership.inputs = ['address'];
Ownable.prototype.transferOwnership.modifiers = ['_onlyOwner'];

Ownable.prototype._transferOwnership.internal = true;

Ownable.prototype._onlyOwner.internal = true;




class ERC20Token extends Ownable {
name = 'ERC20 Token';
symbol = 'ERC20';
decimals = 18;
totalSupply = number('0');

allowed = {};
balances = {};

supportedInterfaces = {
'0x36372b07': true, // ERC20
'0x06fdde03': true, // ERC20 name
'0x95d89b41': true, // ERC20 symbol
'0x313ce567': true, // ERC20 decimals
};


Transfer(sender, recipient, amount) {} // event
Approval(owner, spender, amount) {} // event
Mint(minter, amount) {} // event
Burn(burner, amount) {} // event


balanceOf(holderAddress) {
holderAddress = holderAddress.toLowerCase();
var tokenBalances = this.balances || {};

if (holderAddress in tokenBalances) {
const balance = tokenBalances[holderAddress];
return [balance];
}
return [number(0)];
}

transfer(recipient, amount) {
recipient = recipient.toLowerCase();
const sender = msg.sender;
var tokenBalances = this.balances || {};

if (! (sender in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}

emit('Transfer', [sender, recipient, amount]);
return [true];
}


transferFrom(sender, recipient, amount) {
sender = sender.toLowerCase();
recipient = recipient.toLowerCase();

var tokenBalances = this.balances || {};
var tokenAllowances = this.allowed || {};

require(sender in tokenBalances, 'MISSING_TOKEN_BALANCE');
if (tokenBalances[sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}

require(sender == msg.sender || (sender in tokenAllowances && msg.sender in tokenAllowances[sender]), "MISSING_ALLOWANCE");
if (sender != msg.sender && tokenAllowances[sender][msg.sender].lt(amount)) {
_throw('INSUFFICIENT_TOKEN_ALLOWANCE');
}

tokenAllowances[sender][msg.sender] = tokenAllowances[sender][msg.sender].sub(amount);

if (this._decrementUserBalance.bind(this)(sender, amount)) {
this._incrementUserBalance.bind(this)(recipient, amount)
}


emit('Transfer', [sender, recipient, amount]);
return [true];
}


allowance(owner, spender) {
owner = owner.toLowerCase();
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (owner in tokenAllowances && spender in tokenAllowances[owner]) {
return [tokenAllowances[owner][spender]];
}
return [number(0)];
}

approve(spender, value) {
spender = spender.toLowerCase();
var tokenAllowances = this.allowed || {};
if (! (msg.sender in tokenAllowances)) {
tokenAllowances[msg.sender] = {};
}
tokenAllowances[msg.sender][spender] = value;
emit('Approval', [msg.sender, spender, value]);
return [true];
}


mint(userAddress, amount) {
this._mint(userAddress, amount);
}

_mint(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: mint to the zero address');
}

if (this._incrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.add(amount);
}

emit('Mint', [userAddress, amount]);
}


burn(userAddress, amount) {
this._burn(userAddress, amount);
}

_burn(userAddress, amount) {
userAddress = userAddress.toLowerCase();
if (userAddress == address(0).address) {
_throw('ERC20: burn from the zero address');
}

if (this._decrementUserBalance.bind(this)(userAddress, amount)) {
this.totalSupply = this.totalSupply.sub(amount);
}

emit('Burn', [userAddress, amount]);
}


supportsInterface(interfaceID) {
const _interfaces = this.supportedInterfaces || {};
return [
((interfaceID in _interfaces)
? _interfaces[interfaceID]
: false)
];
}


_decrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
if (amount.gt(tokenBalances[holderAddress])) {
_throw('INSUFFICIENT_TOKEN_BALANCE');
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].sub(amount);
return true;
}


_incrementUserBalance(holderAddress, amount) {
var tokenBalances = this.balances || {};

if (! (holderAddress in tokenBalances)) {
tokenBalances[holderAddress] = number(0);
}
tokenBalances[holderAddress] = tokenBalances[holderAddress].add(amount);
return true;
}

}

// Events
ERC20Token.prototype.Transfer.event = true;
ERC20Token.prototype.Transfer.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Approval.event = true;
ERC20Token.prototype.Approval.inputs = ['address indexed', 'address indexed', 'uint256'];

ERC20Token.prototype.Mint.event = true;
ERC20Token.prototype.Mint.inputs = ['address indexed', 'uint256'];

ERC20Token.prototype.Burn.event = true;
ERC20Token.prototype.Burn.inputs = ['address indexed', 'uint256'];

// Methods
ERC20Token.prototype.balanceOf.view = true;
ERC20Token.prototype.balanceOf.inputs = ['address'];
ERC20Token.prototype.balanceOf.outputs = ['uint256'];

ERC20Token.prototype.transfer.inputs = ['address', 'uint256'];
ERC20Token.prototype.transfer.outputs = ['bool'];

ERC20Token.prototype.transferFrom.inputs = ['address', 'address', 'uint256'];
ERC20Token.prototype.transferFrom.outputs = ['bool'];

ERC20Token.prototype.allowance.view = true;
ERC20Token.prototype.allowance.inputs = ['address', 'address'];
ERC20Token.prototype.allowance.outputs = ['uint256'];

ERC20Token.prototype.approve.inputs = ['address', 'uint256'];
ERC20Token.prototype.approve.outputs = ['bool'];

ERC20Token.prototype.mint.inputs = ['address', 'uint256'];
ERC20Token.prototype.mint.modifiers = ['_onlyOwner'];

ERC20Token.prototype._mint.internal = true;

ERC20Token.prototype.burn.inputs = ['address', 'uint256'];
ERC20Token.prototype.burn.modifiers = ['_onlyOwner'];

ERC20Token.prototype._burn.internal = true;

ERC20Token.prototype.supportsInterface.view = true;
ERC20Token.prototype.supportsInterface.inputs = ['bytes4'];
ERC20Token.prototype.supportsInterface.outputs = ['bool'];

ERC20Token.prototype._decrementUserBalance.internal = true;

ERC20Token.prototype._incrementUserBalance.internal = true;



class BasicToken extends ERC20Token {
name = 'BASIC Token';
symbol = 'BASIC';

constructor() {
super();
this.totalSupply = number('42000000' + '000000000000000000'); // 42 000 000 BASIC
this.balances[msg.sender] = this.totalSupply;
}

}


return BasicToken;
"
, codeHash: "0xc3882317a0d96b82310d94f886a4512c6586eb848541241c62f8d9a5b3f19a68", codeAbi: { 0x8da5cb5b: { constant: true, "inputs": [], name: "owner", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0x06fdde03: { constant: true, "inputs": [], name: "name", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x95d89b41: { constant: true, "inputs": [], name: "symbol", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x313ce567: { constant: true, "inputs": [], name: "decimals", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x18160ddd: { constant: true, "inputs": [], name: "totalSupply", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x19e1fca4: { constant: true, "inputs": [], name: "allowed", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x7bb98a68: { constant: true, "inputs": [], name: "balances", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x037cc0e6: { constant: true, "inputs": [], name: "supportedInterfaces", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xddf252ad: { inputs: [ { name: "sender", type: "address", indexed: true }, { name: "recipient", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Transfer", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x8c5be1e5: { inputs: [ { name: "owner", type: "address", indexed: true }, { name: "spender", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Approval", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x0f6798a5: { inputs: [ { name: "minter", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Mint", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xcc16f5db: { inputs: [ { name: "burner", type: "address", indexed: true }, { name: "amount", type: "uint256", indexed: false } ], name: "Burn", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x70a08231: { inputs: [ { name: "holderAddress", type: "address" } ], name: "balanceOf", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0xa9059cbb: { inputs: [ { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transfer", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x23b872dd: { inputs: [ { name: "sender", type: "address" }, { name: "recipient", type: "address" }, { name: "amount", type: "uint256" } ], name: "transferFrom", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0xdd62ed3e: { inputs: [ { name: "owner", type: "address" }, { name: "spender", type: "address" } ], name: "allowance", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x095ea7b3: { inputs: [ { name: "spender", type: "address" }, { name: "value", type: "uint256" } ], name: "approve", outputs: [ { name: "", type: "bool" } ], stateMutability: "nonpayable", type: "function" }, 0x40c10f19: { inputs: [ { name: "userAddress", type: "address" }, { name: "amount", type: "uint256" } ], name: "mint", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x9dc29fac: { inputs: [ { name: "userAddress", type: "address" }, { name: "amount", type: "uint256" } ], name: "burn", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0x01ffc9a7: { inputs: [ { name: "interfaceID", type: "bytes4" } ], name: "supportsInterface", outputs: [ { name: "", type: "bool" } ], stateMutability: "view", type: "function" }, 0x8be0079c: { inputs: [ { name: "oldOwner", type: "address", indexed: true }, { name: "newOwner", type: "address", indexed: true } ], name: "OwnershipTransferred", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x893d20e8: { "inputs": [], name: "getOwner", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0xf2fde38b: { inputs: [ { name: "newOwner", type: "address" } ], name: "transferOwnership", "outputs": [], stateMutability: "nonpayable", type: "function" } }, contractName: "BasicToken", storage: { owner: "0x131a190fa22cb867abf58193bf9e7640e9fce682", name: "BASIC Token", symbol: "BASIC", decimals: 18, totalSupply: "42000000000000000000000000", "allowed": {}, balances: { 0x131a190fa22cb867abf58193bf9e7640e9fce682: "42000000000000000000000000" }, supportedInterfaces: { 0x36372b07: true, 0x06fdde03: true, 0x95d89b41: true, 0x313ce567: true }, prototype: { address: "0xffafbe052c786154f7e85cbe67f1d118f5b55b25" } }, storageHash: "0xb48d38f93eaa084033fc5970bf96e559c33c4cdc07d889ab00b4d63f9590739d", savedOnBlockNumber: "10" }, 0xff7cee092641a91e3a105bf0df0748bc11216973: { address: "0xff7cee092641a91e3a105bf0df0748bc11216973", balance: "1248999986935000000000", transactions: [ "0x335f64d35e5c9b5879618554417d24c76622c5c22f37a4bfff710f2810af9352" ], code: null, codeHash: null, "codeAbi": [], contractName: null, "storage": {}, storageHash: "0xb48d38f93eaa084033fc5970bf96e559c33c4cdc07d889ab00b4d63f9590739d", savedOnBlockNumber: "39" } }