ETH Price: $3,437.65 (+4.29%)

Token

Sora Token (XOR)
 

Overview

Max Total Supply

108,255,668,340.243555460867591229 XOR

Holders

17,644 ( 0.034%)

Market

Price

$0.00 @ 0.000000 ETH (-12.12%)

Onchain Market Cap

$383,225.07

Circulating Supply Market Cap

$1,386,608.00

Other Info

Token Contract (WITH 18 Decimals)

Balance
3 XOR

Value
$0.00 ( ~0 Eth) [0.0000%]
0x11c01ab64ed02d3bfbfb407653fe098760ace47d
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

SORA is a decentralized autonomous economy system where new XOR tokens are minted and given to producers of new goods and services.

Market

Volume (24H):$358,903.00
Market Capitalization:$1,386,608.00
Circulating Supply:392,341,138,762.00 XOR
Market Data Source: Coinmarketcap

# Exchange Pair Price  24H Volume % Volume
1
Polkaswap
0X0200060000000000000000000000000000000000000000000000000000000000-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$126,991.00
103,695.353 0X0200060000000000000000000000000000000000000000000000000000000000
0.0001%
2
Bitget
XOR-USDT$0.00
0.0000000 Eth
$121,296.00
34,660,721,406.180 XOR
49.5137%
3
Polkaswap
0X0200070000000000000000000000000000000000000000000000000000000000-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$46,593.00
11.780 0X0200070000000000000000000000000000000000000000000000000000000000
0.0000%
4
Uniswap V3 (Ethereum)
0X40FD72257597AA14C7231A7B1AAA29FCE868F677-0XC02AAA39B223FE8D0A0E5C4F27EAD9083C756CC2$0.00
0.0000000 Eth
$38,338.00
10,284,980,893.358 0X40FD72257597AA14C7231A7B1AAA29FCE868F677
14.6923%
5
Polkaswap
0X0200040000000000000000000000000000000000000000000000000000000000-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$19,325.92
1,212,308.086 0X0200040000000000000000000000000000000000000000000000000000000000
0.0017%
6
Polkaswap
0X0200050000000000000000000000000000000000000000000000000000000000-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$17,355.18
97,886,538.416 0X0200050000000000000000000000000000000000000000000000000000000000
0.1398%
7
Polkaswap
0X00EFE45135018136733BE626B380A87AE663CCF6784A25FE9D9D2BE64ACECB9D-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$2,981.00
30,060.918 0X00EFE45135018136733BE626B380A87AE663CCF6784A25FE9D9D2BE64ACECB9D
0.0000%
8
Uniswap V2 (Ethereum)
0X40FD72257597AA14C7231A7B1AAA29FCE868F677-0XC02AAA39B223FE8D0A0E5C4F27EAD9083C756CC2$0.00
0.0000000 Eth
$2,643.26
751,514,397.144 0X40FD72257597AA14C7231A7B1AAA29FCE868F677
1.0736%
9
Polkaswap
0X002D4E9E03F192CC33B128319A049F353DB98FBF4D98F717FD0B7F66A0462142-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$1,048.49
1,517,007.262 0X002D4E9E03F192CC33B128319A049F353DB98FBF4D98F717FD0B7F66A0462142
0.0022%
10
Polkaswap
0X00F2F4FDA40A4BF1FC3769D156FA695532EEC31E265D75068524462C0B80F674-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$971.67
125,269.815 0X00F2F4FDA40A4BF1FC3769D156FA695532EEC31E265D75068524462C0B80F674
0.0002%
11
Polkaswap
0X0200090000000000000000000000000000000000000000000000000000000000-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$483.03
24,181,724,572.260 0X0200090000000000000000000000000000000000000000000000000000000000
34.5442%
12
Polkaswap
0X008BCFD2387D3FC453333557EECB0EFE59FCBA128769B2FEEFDD306E98E66440-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$367.39
39.749 0X008BCFD2387D3FC453333557EECB0EFE59FCBA128769B2FEEFDD306E98E66440
0.0000%
13
Polkaswap
0X0200000000000000000000000000000000000000000000000000000000000000-0X006A271832F44C93BD8692584D85415F0F3DCCEF9748FECD129442C8EDCB4361$0.00
0.0000000 Eth
$98.20
22,454,444.781 0X0200000000000000000000000000000000000000000000000000000000000000
0.0321%
14
Polkaswap
0X006A271832F44C93BD8692584D85415F0F3DCCEF9748FECD129442C8EDCB4361-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$46.81
25,523.923 0X006A271832F44C93BD8692584D85415F0F3DCCEF9748FECD129442C8EDCB4361
0.0000%
15
Polkaswap
0X00EF6658F79D8B560F77B7B20A5D7822F5BC22539C7B4056128258E5829DA517-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.003
560.924 0X00EF6658F79D8B560F77B7B20A5D7822F5BC22539C7B4056128258E5829DA517
0.0000%
16
Polkaswap
0X00438AAC3A91CC6CEE0C8D2F14E4BF7EC4512CA708B180CC0FDA47B0EB1AD538-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0011
0.000 0X00438AAC3A91CC6CEE0C8D2F14E4BF7EC4512CA708B180CC0FDA47B0EB1AD538
0.0000%
17
Polkaswap
0X00567D096A736F33BF78CAD7B01E33463923B9C933EE13AB7E3FB7B23F5F953A-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0009
179.323 0X00567D096A736F33BF78CAD7B01E33463923B9C933EE13AB7E3FB7B23F5F953A
0.0000%
18
Polkaswap
0X008484148DCF23D1B48908393E7A00D5FDC3BF81029A73EECA62A15EBFB1205A-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0009
15.000 0X008484148DCF23D1B48908393E7A00D5FDC3BF81029A73EECA62A15EBFB1205A
0.0000%
19
Polkaswap
0X009D50E95840B7651D42127FE126EBE6E11910A4E267D0AF5838B08CD555DE79-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0007
13,399.083 0X009D50E95840B7651D42127FE126EBE6E11910A4E267D0AF5838B08CD555DE79
0.0000%
20
Polkaswap
0X00449AF28B82575D6AC0E8C6D20E095BE0917E1B0EAA63962A1DC2C6B81C2B0D-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0006
300.000 0X00449AF28B82575D6AC0E8C6D20E095BE0917E1B0EAA63962A1DC2C6B81C2B0D
0.0000%
21
Polkaswap
0X02000F0000000000000000000000000000000000000000000000000000000000-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0006
0.595 0X02000F0000000000000000000000000000000000000000000000000000000000
0.0000%
22
Polkaswap
0X006D336EFFE921106F7817E133686BBC4258A4E0D6FED3A9294D8A8B27312CEE-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0006
124.677 0X006D336EFFE921106F7817E133686BBC4258A4E0D6FED3A9294D8A8B27312CEE
0.0000%
23
Polkaswap
0X0004D3168F737E96B66B72FBB1949A2A23D4EF87182D1E8BF64096F1BB348E0B-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0005
23,236.306 0X0004D3168F737E96B66B72FBB1949A2A23D4EF87182D1E8BF64096F1BB348E0B
0.0000%
24
Polkaswap
0X009BE848DF92A400DA2F217256C88D1A9B1A0304F9B3E90991A67418E1D3B08C-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0004
12.500 0X009BE848DF92A400DA2F217256C88D1A9B1A0304F9B3E90991A67418E1D3B08C
0.0000%
25
Polkaswap
0X003005B2417B5046455E73F7FC39779A013F1A33B4518BCD83A790900DCA49FF-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0004
75.000 0X003005B2417B5046455E73F7FC39779A013F1A33B4518BCD83A790900DCA49FF
0.0000%
26
Polkaswap
0X002CA40397C794E25DBA18CF807910EEB69EB8E81B3F07BB54F7C5D1D8AB76B9-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0004
75.000 0X002CA40397C794E25DBA18CF807910EEB69EB8E81B3F07BB54F7C5D1D8AB76B9
0.0000%
27
Polkaswap
0X0033271716EEC64234A5324506C4558DE27B7C23C42F3E3B74801F98BDFEEBF7-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0004
560.000 0X0033271716EEC64234A5324506C4558DE27B7C23C42F3E3B74801F98BDFEEBF7
0.0000%
28
Polkaswap
0X008294F7B08F568A661DE2B248C34FC574E7E0012A12EF7959EB1A5C6B349E09-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0003
30.000 0X008294F7B08F568A661DE2B248C34FC574E7E0012A12EF7959EB1A5C6B349E09
0.0000%
29
Polkaswap
0X004BAAEB9BF0D5210A51FAB72D10C84A34F53BEA4E0E102D794D531A45EC50F9-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0003
37,500.000 0X004BAAEB9BF0D5210A51FAB72D10C84A34F53BEA4E0E102D794D531A45EC50F9
0.0001%
30
Polkaswap
0X00F40BFF02811AD7BD4F84BFA8DC3C79A61E2A17CD55C8418D553E7FFAF596AC-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0003
0.500 0X00F40BFF02811AD7BD4F84BFA8DC3C79A61E2A17CD55C8418D553E7FFAF596AC
0.0000%
31
Polkaswap
0X0078F4E6C5113B3D8C954DFF62ECE8FC36A8411F86F1CBB48A52527E22E73BE2-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0003
100.000 0X0078F4E6C5113B3D8C954DFF62ECE8FC36A8411F86F1CBB48A52527E22E73BE2
0.0000%
32
Polkaswap
0X00D1FB79BBD1005A678FBF2DE9256B3AFE260E8EEAD49BB07BD3A566F9FE8355-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0003
266.000 0X00D1FB79BBD1005A678FBF2DE9256B3AFE260E8EEAD49BB07BD3A566F9FE8355
0.0000%
33
Polkaswap
0X00E6DF883C9844E34B354B840E3A527F5FC6BFC937138C67908B1C8F2931F3E9-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0002
120.000 0X00E6DF883C9844E34B354B840E3A527F5FC6BFC937138C67908B1C8F2931F3E9
0.0000%
34
Polkaswap
0X0091BD8D8295B25CAB5A7B8B0E44498E678CFC15D872EDE3215F7D4C7635BA36-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0002
0.200 0X0091BD8D8295B25CAB5A7B8B0E44498E678CFC15D872EDE3215F7D4C7635BA36
0.0000%
35
Polkaswap
0X001DA2678BC8B0FF27D17EB4C11CC8E0DEF6C16A141D93253F3AA51276AA7B45-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0002
120.000 0X001DA2678BC8B0FF27D17EB4C11CC8E0DEF6C16A141D93253F3AA51276AA7B45
0.0000%
36
Polkaswap
0X008F925E3E422218604FAC1CC2F06F3EF9C1E244E0D2A9A823E5BD8CE9778434-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0002
10,000.000 0X008F925E3E422218604FAC1CC2F06F3EF9C1E244E0D2A9A823E5BD8CE9778434
0.0000%
37
Polkaswap
0X00EC184EF0B4BD955DB05EEA5A8489AE72888AB6E63682A15BECA1CD39344C8F-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0002
0.021 0X00EC184EF0B4BD955DB05EEA5A8489AE72888AB6E63682A15BECA1CD39344C8F
0.0000%
38
Polkaswap
0X002EAD91A2DE57B8855B53D4A62C25277073FD7F65F7E5E79F4936ED747FCAD0-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0002
120.000 0X002EAD91A2DE57B8855B53D4A62C25277073FD7F65F7E5E79F4936ED747FCAD0
0.0000%
39
Polkaswap
0X007348EB8F0F3CEC730FBF5EEC1B6A842C54D1DF8BED75A9DF084D5EE013E814-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0001
6,000.000 0X007348EB8F0F3CEC730FBF5EEC1B6A842C54D1DF8BED75A9DF084D5EE013E814
0.0000%
40
Polkaswap
0X009134D5C7B7FDA8863985531F456F89BEF5FBD76684A8ACDB737B3E451D0877-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0001
70.000 0X009134D5C7B7FDA8863985531F456F89BEF5FBD76684A8ACDB737B3E451D0877
0.0000%
41
Polkaswap
0X003252667A82D2DD70FA046EEA663EAEC1F2E37C20879F113B880B04C5EBD805-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0001
72,043,765.217 0X003252667A82D2DD70FA046EEA663EAEC1F2E37C20879F113B880B04C5EBD805
0.1029%
42
Polkaswap
0X002676C3EDEA5B08BC0F9B6809A91AA313B7DA35E28B190222E9DC032BF1E662-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.0001
0.006 0X002676C3EDEA5B08BC0F9B6809A91AA313B7DA35E28B190222E9DC032BF1E662
0.0000%
43
Polkaswap
0X00521AD5CAEADC2E3E04BE4D4EBB0B7C8C9B71BA657C2362A3953490EBC81410-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.00
0.700 0X00521AD5CAEADC2E3E04BE4D4EBB0B7C8C9B71BA657C2362A3953490EBC81410
0.0000%
44
Polkaswap
0X00DBD45AF9F2EA406746F9025110297469E9D29EFC60DF8D88EFB9B0179D6C2C-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.00
0.300 0X00DBD45AF9F2EA406746F9025110297469E9D29EFC60DF8D88EFB9B0179D6C2C
0.0000%
45
Polkaswap
0X00E40BCD6EE5363D3ABBB4603273AA2F6BB89E29323729E884A8EF9C991FE73E-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.00
5.000 0X00E40BCD6EE5363D3ABBB4603273AA2F6BB89E29323729E884A8EF9C991FE73E
0.0000%
46
Polkaswap
0X004D9058620EB7AA4EA243DC6CEFC4B76C0CF7AD941246066142C871B376BB7E-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.00
150.000 0X004D9058620EB7AA4EA243DC6CEFC4B76C0CF7AD941246066142C871B376BB7E
0.0000%
47
Polkaswap
0X002C48630DCB8C75CC36162CBDBC8FF27B843973B951BA9B6E260F869D45BCDC-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.00
0.000 0X002C48630DCB8C75CC36162CBDBC8FF27B843973B951BA9B6E260F869D45BCDC
0.0000%
48
Polkaswap
0X007E908E399CC73F3DAD9F02F9C5C83A7ADCD07E78DD91676FF3C002E245D8E9-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.00
0.100 0X007E908E399CC73F3DAD9F02F9C5C83A7ADCD07E78DD91676FF3C002E245D8E9
0.0000%
49
Polkaswap
0X009E199267A6A2C8AE075BB8D4C40EE8D05C1B769085EE59CE98E50C2B2D8756-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.00
1.000 0X009E199267A6A2C8AE075BB8D4C40EE8D05C1B769085EE59CE98E50C2B2D8756
0.0000%
50
Polkaswap
0X001F7A13792061236ADFC93FA3AA8BAD1DC8A8E8F889432B3D8D416B986F2C43-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.00
10.000 0X001F7A13792061236ADFC93FA3AA8BAD1DC8A8E8F889432B3D8D416B986F2C43
0.0000%
51
Polkaswap
0X0080EDC40A944D29562B2DEA2DE42ED27B9047D16EEEA27C5BC1B2E02786ABE9-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.00
0.300 0X0080EDC40A944D29562B2DEA2DE42ED27B9047D16EEEA27C5BC1B2E02786ABE9
0.0000%
52
Polkaswap
0X0044AEE0776CFB826434AF8EF0F8E2C7E9E6644CFDA0AE0F02C471B1EEBC2483-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.00
0.200 0X0044AEE0776CFB826434AF8EF0F8E2C7E9E6644CFDA0AE0F02C471B1EEBC2483
0.0000%
53
Polkaswap
0X0047E323378D23116261954E67836F350C45625124BBADB35404D9109026FEB5-0X0200000000000000000000000000000000000000000000000000000000000000$0.00
0.0000000 Eth
$0.00
3.067 0X0047E323378D23116261954E67836F350C45625124BBADB35404D9109026FEB5
0.0000%

Contract Source Code Verified (Exact Match)

Contract Name:
SoraToken

Compiler Version
v0.5.9+commit.e560f70d

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity Multiple files format)

File 17 of 21: SoraToken.sol
pragma solidity ^0.5.8;

import "./ERC20Detailed.sol";
import "./ERC20Burnable.sol";
import "./Ownable.sol";

contract SoraToken is ERC20Burnable, ERC20Detailed, Ownable {

    uint256 public constant INITIAL_SUPPLY = 0;

    /**
     * @dev Constructor that gives msg.sender all of existing tokens.
     */
    constructor() public ERC20Detailed("Sora Token", "XOR", 18) {
        _mint(msg.sender, INITIAL_SUPPLY);
    }

    function mintTokens(address beneficiary, uint256 amount) public onlyOwner {
        _mint(beneficiary, amount);
    }

}

File 1 of 21: BasicToken.sol
//! The basic-coin ECR20-compliant token contract.
//!
//! Copyright 2016 Gavin Wood, Parity Technologies Ltd.
//!
//! Licensed under the Apache License, Version 2.0 (the "License");
//! you may not use this file except in compliance with the License.
//! You may obtain a copy of the License at
//!
//!     http://www.apache.org/licenses/LICENSE-2.0
//!
//! Unless required by applicable law or agreed to in writing, software
//! distributed under the License is distributed on an "AS IS" BASIS,
//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//! See the License for the specific language governing permissions and
//! limitations under the License.

pragma solidity ^0.5.8;

contract Owned {
	modifier only_owner { require(msg.sender == owner); _; }

	event NewOwner(address indexed old, address indexed current);

    function setOwner(address _new) only_owner public { emit NewOwner(owner, _new); owner = _new; }

	address public owner = msg.sender;
}

interface Token {
	event Transfer(address indexed from, address indexed to, uint256 value);
	event Approval(address indexed owner, address indexed spender, uint256 value);

	function balanceOf(address _owner) view external returns (uint256 balance);
	function transfer(address _to, uint256 _value) external returns (bool success);
	function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
	function approve(address _spender, uint256 _value) external returns (bool success);
	function allowance(address _owner, address _spender) view external returns (uint256 remaining);
}

// TokenReg interface
contract TokenReg {
	function register(address _addr, string memory _tla, uint _base, string memory _name) public payable returns (bool);
	function registerAs(address _addr, string memory _tla, uint _base, string memory _name, address _owner) public payable returns (bool);
	function unregister(uint _id) public;
	function setFee(uint _fee) public;
	function tokenCount() public view returns (uint);
	function token(uint _id) public view returns (address addr, string memory tla, uint base, string memory name, address owner);
	function fromAddress(address _addr) public view returns (uint id, string memory tla, uint base, string memory name, address owner);
	function fromTLA(string memory _tla) public view returns (uint id, address addr, uint base, string memory name, address owner);
	function meta(uint _id, bytes32 _key) public view returns (bytes32);
	function setMeta(uint _id, bytes32 _key, bytes32 _value) public;
	function drain() public;
	uint public fee;
}

// BasicCoin, ECR20 tokens that all belong to the owner for sending around
contract BasicCoin is Owned, Token {
	// this is as basic as can be, only the associated balance & allowances
	struct Account {
		uint balance;
		mapping (address => uint) allowanceOf;
	}

	// the balance should be available
	modifier when_owns(address _owner, uint _amount) {
		if (accounts[_owner].balance < _amount) revert();
		_;
	}

	// an allowance should be available
	modifier when_has_allowance(address _owner, address _spender, uint _amount) {
		if (accounts[_owner].allowanceOf[_spender] < _amount) revert();
		_;
	}



	// a value should be > 0
	modifier when_non_zero(uint _value) {
		if (_value == 0) revert();
		_;
	}

	bool public called = false;

	// the base, tokens denoted in micros
	uint constant public base = 1000000;

	// available token supply
	uint public totalSupply;

	// storage and mapping of all balances & allowances
	mapping (address => Account) accounts;

	// constructor sets the parameters of execution, _totalSupply is all units
	constructor(uint _totalSupply, address _owner) public   when_non_zero(_totalSupply) {
		totalSupply = _totalSupply;
		owner = _owner;
		accounts[_owner].balance = totalSupply;
	}

	// balance of a specific address
	function balanceOf(address _who) public view returns (uint256) {
		return accounts[_who].balance;
	}

	// transfer
	function transfer(address _to, uint256 _value) public   when_owns(msg.sender, _value) returns (bool) {
		emit Transfer(msg.sender, _to, _value);
		accounts[msg.sender].balance -= _value;
		accounts[_to].balance += _value;

		return true;
	}

	// transfer via allowance
	function transferFrom(address _from, address _to, uint256 _value) public   when_owns(_from, _value) when_has_allowance(_from, msg.sender, _value) returns (bool) {
		called = true;
		emit Transfer(_from, _to, _value);
		accounts[_from].allowanceOf[msg.sender] -= _value;
		accounts[_from].balance -= _value;
		accounts[_to].balance += _value;

		return true;
	}

	// approve allowances
	function approve(address _spender, uint256 _value) public   returns (bool) {
		emit Approval(msg.sender, _spender, _value);
		accounts[msg.sender].allowanceOf[_spender] += _value;

		return true;
	}

	// available allowance
	function allowance(address _owner, address _spender) public view returns (uint256) {
		return accounts[_owner].allowanceOf[_spender];
	}

	// no default function, simple contract only, entry-level users
	function() external {
		revert();
	}
}

// Manages BasicCoin instances, including the deployment & registration
contract BasicCoinManager is Owned {
	// a structure wrapping a deployed BasicCoin
	struct Coin {
		address coin;
		address owner;
		address tokenreg;
	}

	// a new BasicCoin has been deployed
	event Created(address indexed owner, address indexed tokenreg, address indexed coin);

	// a list of all the deployed BasicCoins
	Coin[] coins;

	// all BasicCoins for a specific owner
	mapping (address => uint[]) ownedCoins;

	// the base, tokens denoted in micros (matches up with BasicCoin interface above)
	uint constant public base = 1000000;

	// return the number of deployed
	function count() public view returns (uint) {
		return coins.length;
	}

	// get a specific deployment
	function get(uint _index) public view returns (address coin, address owner, address tokenreg) {
		Coin memory c = coins[_index];

		coin = c.coin;
		owner = c.owner;
		tokenreg = c.tokenreg;
	}

	// returns the number of coins for a specific owner
	function countByOwner(address _owner) public view returns (uint) {
		return ownedCoins[_owner].length;
	}

	// returns a specific index by owner
	function getByOwner(address _owner, uint _index) public view returns (address coin, address owner, address tokenreg) {
		return get(ownedCoins[_owner][_index]);
	}

	// deploy a new BasicCoin on the blockchain
	function deploy(uint _totalSupply, string memory _tla, string memory _name, address _tokenreg) public payable returns (bool) {
		TokenReg tokenreg = TokenReg(_tokenreg);
		BasicCoin coin = new BasicCoin(_totalSupply, msg.sender);

		uint ownerCount = countByOwner(msg.sender);
		uint fee = tokenreg.fee();

		ownedCoins[msg.sender].length = ownerCount + 1;
		ownedCoins[msg.sender][ownerCount] = coins.length;
		coins.push(Coin(address(coin), msg.sender, address(tokenreg)));
		tokenreg.registerAs.value(fee)(address(coin), _tla, base, _name, msg.sender);

		emit Created(msg.sender, address(tokenreg), address(coin));

		return true;
	}

	// owner can withdraw all collected funds
	function drain() public only_owner {
		if (!msg.sender.send(address(this).balance)) {
			revert();
		}
	}
}

File 2 of 21: ERC20.sol
pragma solidity ^0.5.8;

import "./IERC20.sol";
import "./SafeMath.sol";

/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
 * Originally based on code by FirstBlood:
 * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 *
 * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for
 * all accounts just by listening to said events. Note that this isn't required by the specification, and other
 * compliant implementations may not do it.
 */
contract ERC20 is IERC20 {
    using SafeMath for uint256;

    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowed;

    uint256 private _totalSupply;

    /**
    * @dev Total number of tokens in existence
    */
    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    /**
    * @dev Gets the balance of the specified address.
    * @param owner The address to query the balance of.
    * @return An uint256 representing the amount owned by the passed address.
    */
    function balanceOf(address owner) public view returns (uint256) {
        return _balances[owner];
    }

    /**
     * @dev Function to check the amount of tokens that an owner allowed to a spender.
     * @param owner address The address which owns the funds.
     * @param spender address The address which will spend the funds.
     * @return A uint256 specifying the amount of tokens still available for the spender.
     */
    function allowance(address owner, address spender) public view returns (uint256) {
        return _allowed[owner][spender];
    }

    /**
    * @dev Transfer token for a specified address
    * @param to The address to transfer to.
    * @param value The amount to be transferred.
    */
    function transfer(address to, uint256 value) public returns (bool) {
        _transfer(msg.sender, to, value);
        return true;
    }

    /**
     * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
     * Beware that changing an allowance with this method brings the risk that someone may use both the old
     * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
     * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     */
    function approve(address spender, uint256 value) public returns (bool) {
        _approve(msg.sender, spender, value);
        return true;
    }

    /**
     * @dev Transfer tokens from one address to another.
     * Note that while this function emits an Approval event, this is not required as per the specification,
     * and other compliant implementations may not emit the event.
     * @param from address The address which you want to send tokens from
     * @param to address The address which you want to transfer to
     * @param value uint256 the amount of tokens to be transferred
     */
    function transferFrom(address from, address to, uint256 value) public returns (bool) {
        _transfer(from, to, value);
        _approve(from, msg.sender, _allowed[from][msg.sender].sub(value));
        return true;
    }

    /**
     * @dev Increase the amount of tokens that an owner allowed to a spender.
     * approve should be called when allowed_[_spender] == 0. To increment
     * allowed value is better to use this function to avoid 2 calls (and wait until
     * the first transaction is mined)
     * From MonolithDAO Token.sol
     * Emits an Approval event.
     * @param spender The address which will spend the funds.
     * @param addedValue The amount of tokens to increase the allowance by.
     */
    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
        _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Decrease the amount of tokens that an owner allowed to a spender.
     * approve should be called when allowed_[_spender] == 0. To decrement
     * allowed value is better to use this function to avoid 2 calls (and wait until
     * the first transaction is mined)
     * From MonolithDAO Token.sol
     * Emits an Approval event.
     * @param spender The address which will spend the funds.
     * @param subtractedValue The amount of tokens to decrease the allowance by.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
        _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue));
        return true;
    }

    /**
    * @dev Transfer token for a specified addresses
    * @param from The address to transfer from.
    * @param to The address to transfer to.
    * @param value The amount to be transferred.
    */
    function _transfer(address from, address to, uint256 value) internal {
        require(to != address(0));

        _balances[from] = _balances[from].sub(value);
        _balances[to] = _balances[to].add(value);
        emit Transfer(from, to, value);
    }

    /**
     * @dev Internal function that mints an amount of the token and assigns it to
     * an account. This encapsulates the modification of balances such that the
     * proper events are emitted.
     * @param account The account that will receive the created tokens.
     * @param value The amount that will be created.
     */
    function _mint(address account, uint256 value) internal {
        require(account != address(0));

        _totalSupply = _totalSupply.add(value);
        _balances[account] = _balances[account].add(value);
        emit Transfer(address(0), account, value);
    }

    /**
     * @dev Internal function that burns an amount of the token of a given
     * account.
     * @param account The account whose tokens will be burnt.
     * @param value The amount that will be burnt.
     */
    function _burn(address account, uint256 value) internal {
        require(account != address(0));

        _totalSupply = _totalSupply.sub(value);
        _balances[account] = _balances[account].sub(value);
        emit Transfer(account, address(0), value);
    }

    /**
     * @dev Approve an address to spend another addresses' tokens.
     * @param owner The address that owns the tokens.
     * @param spender The address that will spend the tokens.
     * @param value The number of tokens that can be spent.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        require(spender != address(0));
        require(owner != address(0));

        _allowed[owner][spender] = value;
        emit Approval(owner, spender, value);
    }

    /**
     * @dev Internal function that burns an amount of the token of a given
     * account, deducting from the sender's allowance for said account. Uses the
     * internal burn function.
     * Emits an Approval event (reflecting the reduced allowance).
     * @param account The account whose tokens will be burnt.
     * @param value The amount that will be burnt.
     */
    function _burnFrom(address account, uint256 value) internal {
        _burn(account, value);
        _approve(account, msg.sender, _allowed[account][msg.sender].sub(value));
    }
}

File 3 of 21: ERC20Burnable.sol
pragma solidity ^0.5.8;

import "./ERC20.sol";

/**
 * @title Burnable Token
 * @dev Token that can be irreversibly burned (destroyed).
 */
contract ERC20Burnable is ERC20 {
    /**
     * @dev Burns a specific amount of tokens.
     * @param value The amount of token to be burned.
     */
    function burn(uint256 value) public {
        _burn(msg.sender, value);
    }

    /**
     * @dev Burns a specific amount of tokens from the target address and decrements allowance
     * @param from address The address which you want to send tokens from
     * @param value uint256 The amount of token to be burned
     */
    function burnFrom(address from, uint256 value) public {
        _burnFrom(from, value);
    }
}

File 4 of 21: ERC20Detailed.sol
pragma solidity ^0.5.8;

import "./IERC20.sol";

/**
 * @title ERC20Detailed token
 * @dev The decimals are only for visualization purposes.
 * All the operations are done using the smallest and indivisible token unit,
 * just as on Ethereum all the operations are done in wei.
 */
contract ERC20Detailed is IERC20 {
    string private _name;
    string private _symbol;
    uint8 private _decimals;

    constructor (string memory name, string memory symbol, uint8 decimals) public {
        _name = name;
        _symbol = symbol;
        _decimals = decimals;
    }

    /**
     * @return the name of the token.
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @return the symbol of the token.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @return the number of decimals of the token.
     */
    function decimals() public view returns (uint8) {
        return _decimals;
    }
}

File 5 of 21: Failer.sol
pragma solidity ^0.5.8;

/**
 * Contract for revert cases testing
 */
contract Failer {
    /**
     * A special function-like stub to allow ether accepting. Always fails.
     */
    function() external payable {
        revert("eth transfer revert");
    }

    /**
     * Fake ERC-20 transfer function. Always fails.
     */
    function transfer(address, uint256) external pure {
        revert("ERC-20 transfer revert");
    }
}

File 6 of 21: IERC20.sol
pragma solidity ^0.5.8;

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
interface IERC20 {
    function transfer(address to, uint256 value) external returns (bool);

    function approve(address spender, uint256 value) external returns (bool);

    function transferFrom(address from, address to, uint256 value) external returns (bool);

    function totalSupply() external view returns (uint256);

    function balanceOf(address who) external view returns (uint256);

    function allowance(address owner, address spender) external view returns (uint256);

    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 7 of 21: IMaster.sol
pragma solidity ^0.5.8;

/**
 * Subset of master contract interface
 */
contract IMaster {
    function withdraw(
        address tokenAddress,
        uint256 amount,
        address to,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s,
        address from
    )
    public;

    function mintTokensByPeers(
        address tokenAddress,
        uint256 amount,
        address beneficiary,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s,
        address from
    )
    public;

    function checkTokenAddress(address token) public view returns (bool);
}

File 8 of 21: IRelayRegistry.sol
pragma solidity ^0.5.8;

/**
 * @title Relay registry interface
 */
interface IRelayRegistry {

    /**
     * Store relay address and appropriate whitelist of addresses
     * @param relay contract address
     * @param whiteList with allowed addresses
     * @return true if data was stored
     */
    function addNewRelayAddress(address relay, address[] calldata whiteList) external;

    /**
     * Check if some address is in the whitelist
     * @param relay contract address
     * @param who address in whitelist
     * @return true if address in the whitelist
     */
    function isWhiteListed(address relay, address who) external view returns (bool);

    /**
     * Get entire whitelist by relay address
     * @param relay contract address
     * @return array of the whitelist
     */
    function getWhiteListByRelay(address relay) external view returns (address[] memory);

    event AddNewRelay (
        address indexed relayAddress,
        address[] indexed whiteList
    );
}

File 9 of 21: Master.sol
pragma solidity ^0.5.8;

import "./IERC20.sol";
import "./SoraToken.sol";

/**
 * Provides functionality of master contract
 */
contract Master {
    bool internal initialized_;
    address public owner_;
    mapping(address => bool) public isPeer;
    uint public peersCount;
    /** Iroha tx hashes used */
    mapping(bytes32 => bool) public used;
    mapping(address => bool) public uniqueAddresses;

    /** registered client addresses */
    mapping(address => bytes) public registeredClients;

    SoraToken public xorTokenInstance;

    mapping(address => bool) public isToken;

    /**
     * Emit event on new registration with iroha acountId
     */
     event IrohaAccountRegistration(address ethereumAddress, bytes accountId);

    /**
     * Emit event when master contract does not have enough assets to proceed withdraw
     */
    event InsufficientFundsForWithdrawal(address asset, address recipient);

    /**
     * Constructor. Sets contract owner to contract creator.
     */
    constructor(address[] memory initialPeers) public {
        initialize(msg.sender, initialPeers);
    }

    /**
     * Initialization of smart contract.
     */
    function initialize(address owner, address[] memory initialPeers) public {
        require(!initialized_);

        owner_ = owner;
        for (uint8 i = 0; i < initialPeers.length; i++) {
            addPeer(initialPeers[i]);
        }

        // 0 means ether which is definitely in whitelist
        isToken[address(0)] = true;

        // Create new instance of Sora token
        xorTokenInstance = new SoraToken();
        isToken[address(xorTokenInstance)] = true;

        initialized_ = true;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner());
        _;
    }

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns(bool) {
        return msg.sender == owner_;
    }

    /**
     * A special function-like stub to allow ether accepting
     */
    function() external payable {
        require(msg.data.length == 0);
    }

    /**
     * Adds new peer to list of signature verifiers. Can be called only by contract owner.
     * @param newAddress address of new peer
     */
    function addPeer(address newAddress) private returns (uint) {
        require(isPeer[newAddress] == false);
        isPeer[newAddress] = true;
        ++peersCount;
        return peersCount;
    }

    function removePeer(address peerAddress) private {
        require(isPeer[peerAddress] == true);
        isPeer[peerAddress] = false;
        --peersCount;
    }

    function addPeerByPeer(
        address newPeerAddress,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s
    )
    public returns (bool)
    {
        require(used[txHash] == false);
        require(checkSignatures(keccak256(abi.encodePacked(newPeerAddress, txHash)),
            v,
            r,
            s)
        );

        addPeer(newPeerAddress);
        used[txHash] = true;
        return true;
    }

    function removePeerByPeer(
        address peerAddress,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s
    )
    public returns (bool)
    {
        require(used[txHash] == false);
        require(checkSignatures(
            keccak256(abi.encodePacked(peerAddress, txHash)),
            v,
            r,
            s)
        );

        removePeer(peerAddress);
        used[txHash] = true;
        return true;
    }

    /**
     * Adds new token to whitelist. Token should not been already added.
     * @param newToken token to add
     */
    function addToken(address newToken) public onlyOwner {
        require(isToken[newToken] == false);
        isToken[newToken] = true;
    }

    /**
     * Checks is given token inside a whitelist or not
     * @param tokenAddress address of token to check
     * @return true if token inside whitelist or false otherwise
     */
    function checkTokenAddress(address tokenAddress) public view returns (bool) {
        return isToken[tokenAddress];
    }

    /**
     * Register a clientIrohaAccountId for the caller clientEthereumAddress
     * @param clientEthereumAddress - ethereum address to register
     * @param clientIrohaAccountId - iroha account id
     * @param txHash - iroha tx hash of registration
     * @param v array of signatures of tx_hash (v-component)
     * @param r array of signatures of tx_hash (r-component)
     * @param s array of signatures of tx_hash (s-component)
     */
    function register(
        address clientEthereumAddress,
        bytes memory clientIrohaAccountId,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s
    )
    public
    {
        require(used[txHash] == false);
        require(checkSignatures(
                    keccak256(abi.encodePacked(clientEthereumAddress, clientIrohaAccountId, txHash)),
                    v,
                    r,
                    s)
                );
        require(clientEthereumAddress == msg.sender);
        require(registeredClients[clientEthereumAddress].length == 0);

        registeredClients[clientEthereumAddress] = clientIrohaAccountId;

        emit IrohaAccountRegistration(clientEthereumAddress, clientIrohaAccountId);
    }

    /**
     * Withdraws specified amount of ether or one of ERC-20 tokens to provided address
     * @param tokenAddress address of token to withdraw (0 for ether)
     * @param amount amount of tokens or ether to withdraw
     * @param to target account address
     * @param txHash hash of transaction from Iroha
     * @param v array of signatures of tx_hash (v-component)
     * @param r array of signatures of tx_hash (r-component)
     * @param s array of signatures of tx_hash (s-component)
     * @param from relay contract address
     */
    function withdraw(
        address tokenAddress,
        uint256 amount,
        address payable to,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s,
        address from
    )
    public
    {
        require(checkTokenAddress(tokenAddress));
        require(used[txHash] == false);
        require(checkSignatures(
            keccak256(abi.encodePacked(tokenAddress, amount, to, txHash, from)),
            v,
            r,
            s)
        );

        if (tokenAddress == address (0)) {
            if (address(this).balance < amount) {
                emit InsufficientFundsForWithdrawal(tokenAddress, to);
            } else {
                used[txHash] = true;
                // untrusted transfer, relies on provided cryptographic proof
                to.transfer(amount);
            }
        } else {
            IERC20 coin = IERC20(tokenAddress);
            if (coin.balanceOf(address (this)) < amount) {
                emit InsufficientFundsForWithdrawal(tokenAddress, to);
            } else {
                used[txHash] = true;
                // untrusted call, relies on provided cryptographic proof
                coin.transfer(to, amount);
            }
        }
    }

    /**
     * Checks given addresses for duplicates and if they are peers signatures
     * @param hash unsigned data
     * @param v v-component of signature from hash
     * @param r r-component of signature from hash
     * @param s s-component of signature from hash
     * @return true if all given addresses are correct or false otherwise
     */
    function checkSignatures(bytes32 hash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s
    ) private returns (bool) {
        require(peersCount >= 1);
        require(v.length == r.length);
        require(r.length == s.length);
        uint needSigs = peersCount - (peersCount - 1) / 3;
        require(s.length >= needSigs);

        uint count = 0;
        address[] memory recoveredAddresses = new address[](s.length);
        for (uint i = 0; i < s.length; ++i) {
            address recoveredAddress = recoverAddress(
                hash,
                v[i],
                r[i],
                s[i]
            );

            // not a peer address or not unique
            if (isPeer[recoveredAddress] != true || uniqueAddresses[recoveredAddress] == true) {
                continue;
            }
            recoveredAddresses[count] = recoveredAddress;
            count = count + 1;
            uniqueAddresses[recoveredAddress] = true;
        }

        // restore state for future usages
        for (uint i = 0; i < count; ++i) {
            uniqueAddresses[recoveredAddresses[i]] = false;
        }

        return count >= needSigs;
    }

    /**
     * Recovers address from a given single signature
     * @param hash unsigned data
     * @param v v-component of signature from hash
     * @param r r-component of signature from hash
     * @param s s-component of signature from hash
     * @return address recovered from signature
     */
    function recoverAddress(bytes32 hash, uint8 v, bytes32 r, bytes32 s) private pure returns (address) {
        bytes32 simple_hash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
        address res = ecrecover(simple_hash, v, r, s);
        return res;
    }

    /**
     * Mint new XORToken
     * @param tokenAddress address to mint
     * @param amount how much to mint
     * @param beneficiary destination address
     * @param txHash hash of transaction from Iroha
     * @param v array of signatures of tx_hash (v-component)
     * @param r array of signatures of tx_hash (r-component)
     * @param s array of signatures of tx_hash (s-component)
     */
    function mintTokensByPeers(
        address tokenAddress,
        uint256 amount,
        address beneficiary,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s,
        address from
    )
    public
    {
        require(address(xorTokenInstance) == tokenAddress);
        require(used[txHash] == false);
        require(checkSignatures(
            keccak256(abi.encodePacked(tokenAddress, amount, beneficiary, txHash, from)),
            v,
            r,
            s)
        );

        xorTokenInstance.mintTokens(beneficiary, amount);
        used[txHash] = true;
    }
}

File 10 of 21: MasterRelayed.sol
pragma solidity ^0.5.8;

import "./IRelayRegistry.sol";
import "./IERC20.sol";
import "./SoraToken.sol";

/**
 * Provides functionality of master contract with relays
 */
contract MasterRelayed {
    bool internal initialized_;
    address public owner_;
    mapping(address => bool) public isPeer;
    /** Iroha tx hashes used */
    uint public peersCount;
    mapping(bytes32 => bool) public used;
    mapping(address => bool) public uniqueAddresses;

    /** registered client addresses */
    address public relayRegistryAddress;
    IRelayRegistry public relayRegistryInstance;

    SoraToken public xorTokenInstance;

    mapping(address => bool) public isToken;

    /**
     * Emit event when master contract does not have enough assets to proceed withdraw
     */
    event InsufficientFundsForWithdrawal(address asset, address recipient);

    /**
     * Constructor. Sets contract owner to contract creator.
     */
    constructor(address relayRegistry, address[] memory initialPeers) public {
        initialize(msg.sender, relayRegistry, initialPeers);
    }

    /**
     * Initialization of smart contract.
     */
    function initialize(address owner, address relayRegistry, address[] memory initialPeers) public {
        require(!initialized_);

        owner_ = owner;
        relayRegistryAddress = relayRegistry;
        relayRegistryInstance = IRelayRegistry(relayRegistryAddress);
        for (uint8 i = 0; i < initialPeers.length; i++) {
            addPeer(initialPeers[i]);
        }

        // 0 means ether which is definitely in whitelist
        isToken[address(0)] = true;

        // Create new instance of Sora token
        xorTokenInstance = new SoraToken();
        isToken[address(xorTokenInstance)] = true;

        initialized_ = true;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner());
        _;
    }

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns(bool) {
        return msg.sender == owner_;
    }

    /**
     * A special function-like stub to allow ether accepting
     */
    function() external payable {
        require(msg.data.length == 0);
    }

    /**
     * Adds new peer to list of signature verifiers. Can be called only by contract owner.
     * @param newAddress address of new peer
     */
    function addPeer(address newAddress) private returns (uint) {
        require(isPeer[newAddress] == false);
        isPeer[newAddress] = true;
        ++peersCount;
        return peersCount;
    }

    function removePeer(address peerAddress) private {
        require(isPeer[peerAddress] == true);
        isPeer[peerAddress] = false;
        --peersCount;
    }

    function addPeerByPeer(
        address newPeerAddress,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s
    )
    public returns (bool)
    {
        require(used[txHash] == false);
        require(checkSignatures(keccak256(abi.encodePacked(newPeerAddress, txHash)),
            v,
            r,
            s)
        );

        addPeer(newPeerAddress);
        used[txHash] = true;
        return true;
    }

    function removePeerByPeer(
        address peerAddress,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s
    )
    public returns (bool)
    {
        require(used[txHash] == false);
        require(checkSignatures(
            keccak256(abi.encodePacked(peerAddress, txHash)),
            v,
            r,
            s)
        );

        removePeer(peerAddress);
        used[txHash] = true;
        return true;
    }

    /**
     * Adds new token to whitelist. Token should not been already added.
     * @param newToken token to add
     */
    function addToken(address newToken) public onlyOwner {
        require(isToken[newToken] == false);
        isToken[newToken] = true;
    }

    /**
     * Checks is given token inside a whitelist or not
     * @param tokenAddress address of token to check
     * @return true if token inside whitelist or false otherwise
     */
    function checkTokenAddress(address tokenAddress) public view returns (bool) {
        return isToken[tokenAddress];
    }

    /**
     * Withdraws specified amount of ether or one of ERC-20 tokens to provided address
     * @param tokenAddress address of token to withdraw (0 for ether)
     * @param amount amount of tokens or ether to withdraw
     * @param to target account address
     * @param txHash hash of transaction from Iroha
     * @param v array of signatures of tx_hash (v-component)
     * @param r array of signatures of tx_hash (r-component)
     * @param s array of signatures of tx_hash (s-component)
     * @param from relay contract address
     */
    function withdraw(
        address tokenAddress,
        uint256 amount,
        address payable to,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s,
        address from
    )
    public
    {
        require(checkTokenAddress(tokenAddress));
        require(relayRegistryInstance.isWhiteListed(from, to));
        require(used[txHash] == false);
        require(checkSignatures(
            keccak256(abi.encodePacked(tokenAddress, amount, to, txHash, from)),
            v,
            r,
            s)
        );

        if (tokenAddress == address (0)) {
            if (address(this).balance < amount) {
                emit InsufficientFundsForWithdrawal(tokenAddress, to);
            } else {
                used[txHash] = true;
                // untrusted transfer, relies on provided cryptographic proof
                to.transfer(amount);
            }
        } else {
            IERC20 coin = IERC20(tokenAddress);
            if (coin.balanceOf(address (this)) < amount) {
                emit InsufficientFundsForWithdrawal(tokenAddress, to);
            } else {
                used[txHash] = true;
                // untrusted call, relies on provided cryptographic proof
                coin.transfer(to, amount);
            }
        }
    }

    /**
     * Checks given addresses for duplicates and if they are peers signatures
     * @param hash unsigned data
     * @param v v-component of signature from hash
     * @param r r-component of signature from hash
     * @param s s-component of signature from hash
     * @return true if all given addresses are correct or false otherwise
     */
    function checkSignatures(bytes32 hash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s
    ) private returns (bool) {
        require(peersCount >= 1);
        require(v.length == r.length);
        require(r.length == s.length);
        uint needSigs = peersCount - (peersCount - 1) / 3;
        require(s.length >= needSigs);

        uint count = 0;
        address[] memory recoveredAddresses = new address[](s.length);
        for (uint i = 0; i < s.length; ++i) {
            address recoveredAddress = recoverAddress(
                hash,
                v[i],
                r[i],
                s[i]
            );

            // not a peer address or not unique
            if (isPeer[recoveredAddress] != true || uniqueAddresses[recoveredAddress] == true) {
                continue;
            }
            recoveredAddresses[count] = recoveredAddress;
            count = count + 1;
            uniqueAddresses[recoveredAddress] = true;
        }

        // restore state for future usages
        for (uint i = 0; i < count; ++i) {
            uniqueAddresses[recoveredAddresses[i]] = false;
        }

        return count >= needSigs;
    }

    /**
     * Recovers address from a given single signature
     * @param hash unsigned data
     * @param v v-component of signature from hash
     * @param r r-component of signature from hash
     * @param s s-component of signature from hash
     * @return address recovered from signature
     */
    function recoverAddress(bytes32 hash, uint8 v, bytes32 r, bytes32 s) private pure returns (address) {
        bytes32 simple_hash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
        address res = ecrecover(simple_hash, v, r, s);
        return res;
    }

    /**
     * Mint new XORToken
     * @param tokenAddress address to mint
     * @param amount how much to mint
     * @param beneficiary destination address
     * @param txHash hash of transaction from Iroha
     * @param v array of signatures of tx_hash (v-component)
     * @param r array of signatures of tx_hash (r-component)
     * @param s array of signatures of tx_hash (s-component)
     */
    function mintTokensByPeers(
        address tokenAddress,
        uint256 amount,
        address beneficiary,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s,
        address from
    )
    public
    {
        require(address(xorTokenInstance) == tokenAddress);
        require(relayRegistryInstance.isWhiteListed(from, beneficiary));
        require(used[txHash] == false);
        require(checkSignatures(
            keccak256(abi.encodePacked(tokenAddress, amount, beneficiary, txHash, from)),
            v,
            r,
            s)
        );

        xorTokenInstance.mintTokens(beneficiary, amount);
        used[txHash] = true;
    }
}

File 11 of 21: Ownable.sol
pragma solidity ^0.5.8;

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
     * account.
     */
    constructor () internal {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @return the address of the owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner());
        _;
    }

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    /**
     * @dev Allows the current owner to relinquish control of the contract.
     * @notice Renouncing to ownership will leave the contract without an owner.
     * It will not be possible to call the functions with the `onlyOwner`
     * modifier anymore.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0));
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

File 12 of 21: OwnedUpgradeabilityProxy.sol
pragma solidity ^0.5.8;

import './UpgradeabilityProxy.sol';

/**
 * @title OwnedUpgradeabilityProxy
 * @dev This contract combines an upgradeability proxy with basic authorization control functionalities
 */
contract OwnedUpgradeabilityProxy is UpgradeabilityProxy {
  /**
  * @dev Event to show ownership has been transferred
  * @param previousOwner representing the address of the previous owner
  * @param newOwner representing the address of the new owner
  */
  event ProxyOwnershipTransferred(address previousOwner, address newOwner);

  // Storage position of the owner of the contract
  bytes32 private constant proxyOwnerPosition = keccak256("com.d3ledger.proxy.owner");

  /**
  * @dev the constructor sets the original owner of the contract to the sender account.
  */
  constructor() public {
    setUpgradeabilityOwner(msg.sender);
  }

  /**
  * @dev Throws if called by any account other than the owner.
  */
  modifier onlyProxyOwner() {
    require(msg.sender == proxyOwner());
    _;
  }

  /**
   * @dev Tells the address of the owner
   * @return the address of the owner
   */
  function proxyOwner() public view returns (address owner) {
    bytes32 position = proxyOwnerPosition;
    assembly {
      owner := sload(position)
    }
  }

  /**
   * @dev Sets the address of the owner
   */
  function setUpgradeabilityOwner(address newProxyOwner) internal {
    bytes32 position = proxyOwnerPosition;
    assembly {
      sstore(position, newProxyOwner)
    }
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferProxyOwnership(address newOwner) public onlyProxyOwner {
    require(newOwner != address(0));
    emit ProxyOwnershipTransferred(proxyOwner(), newOwner);
    setUpgradeabilityOwner(newOwner);
  }

  /**
   * @dev Allows the proxy owner to upgrade the current version of the proxy.
   * @param implementation representing the address of the new implementation to be set.
   */
  function upgradeTo(address implementation) public onlyProxyOwner {
    _upgradeTo(implementation);
  }

  /**
   * @dev Allows the proxy owner to upgrade the current version of the proxy and call the new implementation
   * to initialize whatever is needed through a low level call.
   * @param implementation representing the address of the new implementation to be set.
   * @param data represents the msg.data to bet sent in the low level call. This parameter may include the function
   * signature of the implementation to be called with the needed payload
   */
  function upgradeToAndCall(address implementation, bytes memory data) payable public onlyProxyOwner {
    upgradeTo(implementation);
    (bool success,) = address(this).call.value(msg.value)(data);
    require(success);
  }
}

File 13 of 21: Proxy.sol
pragma solidity ^0.5.8;

/**
 * @title Proxy
 * @dev Gives the possibility to delegate any call to a foreign implementation.
 */
contract Proxy {
  /**
  * @dev Tells the address of the implementation where every call will be delegated.
  * @return address of the implementation to which it will be delegated
  */
  function implementation() public view returns (address);

  /**
  * @dev Fallback function allowing to perform a delegatecall to the given implementation.
  * This function will return whatever the implementation call returns
  */
  function () payable external {
    address _impl = implementation();
    require(_impl != address(0));

    assembly {
      let ptr := mload(0x40)
      calldatacopy(ptr, 0, calldatasize)
      let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0)
      let size := returndatasize
      returndatacopy(ptr, 0, size)

      switch result
      case 0 { revert(ptr, size) }
      default { return(ptr, size) }
    }
  }
}

File 14 of 21: Relay.sol
pragma solidity ^0.5.8;

import "./IMaster.sol";
import "./IERC20.sol";

/**
 * Provides functionality of relay contract
 */
contract Relay {
    bool internal initialized_;
    address payable private masterAddress;
    IMaster private masterInstance;

    event AddressEvent(address input);
    event StringEvent(string input);
    event BytesEvent(bytes32 input);
    event NumberEvent(uint256 input);

    /**
     * Relay constructor
     * @param master address of master contract
     */
    constructor(address payable master) public {
        initialize(master);
    }

    /**
     * Initialization of smart contract.
     */
    function initialize(address payable master) public {
        require(!initialized_);
        masterAddress = master;
        masterInstance = IMaster(masterAddress);
        initialized_ = true;
    }

    /**
     * A special function-like stub to allow ether accepting
     */
    function() external payable {
        require(msg.data.length == 0);
        emit AddressEvent(msg.sender);
    }

    /**
     * Sends ether and all tokens from this contract to master
     * @param tokenAddress address of sending token (0 for Ether)
     */
    function sendToMaster(address tokenAddress) public {
        // trusted call
        require(masterInstance.checkTokenAddress(tokenAddress));
        if (tokenAddress == address(0)) {
            // trusted transfer
            masterAddress.transfer(address(this).balance);
        } else {
            IERC20 ic = IERC20(tokenAddress);
            // untrusted call in general but coin addresses are received from trusted master contract
            // which contains and manages whitelist of them
            ic.transfer(masterAddress, ic.balanceOf(address(this)));
        }
    }

    /**
     * Withdraws specified amount of ether or one of ERC-20 tokens to provided address
     * @param tokenAddress address of token to withdraw (0 for ether)
     * @param amount amount of tokens or ether to withdraw
     * @param to target account address
     * @param tx_hash hash of transaction from Iroha
     * @param v array of signatures of tx_hash (v-component)
     * @param r array of signatures of tx_hash (r-component)
     * @param s array of signatures of tx_hash (s-component)
     * @param from relay contract address
     */
    function withdraw(
        address tokenAddress,
        uint256 amount,
        address payable to,
        bytes32 tx_hash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s,
        address from
    )
    public
    {
        emit AddressEvent(masterAddress);
        // trusted call
        masterInstance.withdraw(tokenAddress, amount, to, tx_hash, v, r, s, from);
    }

    /**
     * Mint specified amount of ether or one of ERC-20 tokens to provided address
     * @param tokenAddress address to mint
     * @param amount how much to mint
     * @param beneficiary destination address
     * @param txHash hash of transaction from Iroha
     * @param v array of signatures of tx_hash (v-component)
     * @param r array of signatures of tx_hash (r-component)
     * @param s array of signatures of tx_hash (s-component)
     * @param from relay contract address
     */
    function mintTokensByPeers(
        address tokenAddress,
        uint256 amount,
        address beneficiary,
        bytes32 txHash,
        uint8[] memory v,
        bytes32[] memory r,
        bytes32[] memory s,
        address from
    )
    public
    {
        emit AddressEvent(masterAddress);
        // trusted call
        masterInstance.mintTokensByPeers(tokenAddress, amount, beneficiary, txHash, v, r, s, from);
    }
}

File 15 of 21: RelayRegistry.sol
pragma solidity ^0.5.8;

import "./IRelayRegistry.sol";

/**
 * @title Relay registry store data about white list and provide interface for master
 */
contract RelayRegistry is IRelayRegistry {
    bool internal initialized_;
    address private owner_;

    mapping(address => address[]) private _relayWhiteList;

    constructor () public {
        initialize(msg.sender);
    }

    /**
     * Initialization of smart contract.
     */
    function initialize(address owner) public {
        require(!initialized_);
        owner_ = owner;
        initialized_ = true;
    }

    /**
     * Store relay address and appropriate whitelist of addresses
     * @param relay contract address
     * @param whiteList white list
     */
    function addNewRelayAddress(address relay, address[] calldata whiteList) external {
        require(msg.sender == owner_);
        require(_relayWhiteList[relay].length == 0);
        _relayWhiteList[relay] = whiteList;
        emit AddNewRelay(relay, whiteList);
    }

    /**
     * Check if some address is in the whitelist
     * @param relay contract address
     * @param who address in whitelist
     * @return true if address in the whitelist
     */
    function isWhiteListed(address relay, address who) external view returns (bool) {
        if (_relayWhiteList[relay].length == 0) {
            return true;
        }
        if (_relayWhiteList[relay].length > 0) {
            for (uint i = 0; i < _relayWhiteList[relay].length; i++) {
                if (who == _relayWhiteList[relay][i]) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Get entire whitelist by relay address
     * @param relay contract address
     * @return array of the whitelist
     */
    function getWhiteListByRelay(address relay) external view returns (address[] memory ) {
        require(relay != address(0));
        require(_relayWhiteList[relay].length != 0);
        return _relayWhiteList[relay];
    }
}

File 16 of 21: SafeMath.sol
pragma solidity ^0.5.8;

/**
 * @title SafeMath
 * @dev Unsigned math operations with safety checks that revert on error
 */
library SafeMath {
    /**
    * @dev Multiplies two unsigned integers, reverts on overflow.
    */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);

        return c;
    }

    /**
    * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
    */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
    * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
    */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        uint256 c = a - b;

        return c;
    }

    /**
    * @dev Adds two unsigned integers, reverts on overflow.
    */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);

        return c;
    }

    /**
    * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
    * reverts when dividing by zero.
    */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0);
        return a % b;
    }
}

File 18 of 21: TestGreeter_v0.sol
pragma solidity ^0.5.8;

contract TestGreeter_v0 {
    bool ininialized_;

    string greeting_;

    constructor(string memory greeting) public {
        initialize(greeting);
    }

    function initialize(string memory greeting) public {
        require(!ininialized_);
        greeting_ = greeting;
        ininialized_ = true;
    }

    function greet() view public returns (string memory) {
        return greeting_;
    }

    function set(string memory greeting) public {
        greeting_ = greeting;
    }
}

File 19 of 21: TestGreeter_v1.sol
pragma solidity ^0.5.8;

import './TestGreeter_v0.sol';

contract TestGreeter_v1 is TestGreeter_v0("Hi, World!") {

    function farewell() public view returns (string memory) {
        return "Good bye!";
    }
}

File 20 of 21: TransferEthereum.sol
pragma solidity ^0.5.8;

/**
 * Contract that sends Ether with internal transaction for testing purposes.
 */
contract TransferEthereum {


    /**
     * A special function-like stub to allow ether accepting
     */
    function() external payable {
        require(msg.data.length == 0);
    }

    function transfer(address payable to, uint256 amount) public {
        to.call.value(amount)("");
    }

}

File 21 of 21: UpgradeabilityProxy.sol
pragma solidity ^0.5.8;

import './Proxy.sol';

/**
 * @title UpgradeabilityProxy
 * @dev This contract represents a proxy where the implementation address to which it will delegate can be upgraded
 */
contract UpgradeabilityProxy is Proxy {
  /**
   * @dev This event will be emitted every time the implementation gets upgraded
   * @param implementation representing the address of the upgraded implementation
   */
  event Upgraded(address indexed implementation);

  // Storage position of the address of the current implementation
  bytes32 private constant implementationPosition = keccak256("com.d3ledger.proxy.implementation");

  /**
   * @dev Constructor function
   */
  constructor() public {}

  /**
   * @dev Tells the address of the current implementation
   * @return address of the current implementation
   */
  function implementation() public view returns (address impl) {
    bytes32 position = implementationPosition;
    assembly {
      impl := sload(position)
    }
  }

  /**
   * @dev Sets the address of the current implementation
   * @param newImplementation address representing the new implementation to be set
   */
  function setImplementation(address newImplementation) internal {
    bytes32 position = implementationPosition;
    assembly {
      sstore(position, newImplementation)
    }
  }

  /**
   * @dev Upgrades the implementation address
   * @param newImplementation representing the address of the new implementation to be set
   */
  function _upgradeTo(address newImplementation) internal {
    address currentImplementation = implementation();
    require(currentImplementation != newImplementation);
    setImplementation(newImplementation);
    emit Upgraded(newImplementation);
  }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"INITIAL_SUPPLY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"amount","type":"uint256"}],"name":"mintTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]

60806040523480156200001157600080fd5b506040518060400160405280600a81526020017f536f726120546f6b656e000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f584f520000000000000000000000000000000000000000000000000000000000815250601282600390805190602001906200009892919062000204565b508151620000ae90600490602085019062000204565b506005805460ff191660ff9290921691909117610100600160a81b03191661010033810291909117918290556040516001600160a01b0391909204169250600091507f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36200012b3360006001600160e01b036200013116565b620002a9565b6001600160a01b0382166200014557600080fd5b6200016181600254620001ea60201b620008901790919060201c565b6002556001600160a01b038216600090815260208181526040909120546200019491839062000890620001ea821b17901c565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082820183811015620001fd57600080fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200024757805160ff191683800117855562000277565b8280016001018555821562000277579182015b82811115620002775782518255916020019190600101906200025a565b506200028592915062000289565b5090565b620002a691905b8082111562000285576000815560010162000290565b90565b610aec80620002b96000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c8063715018a6116100ad578063a457c2d711610071578063a457c2d714610332578063a9059cbb1461035e578063dd62ed3e1461038a578063f0dda65c146103b8578063f2fde38b146103e457610121565b8063715018a6146102ca57806379cc6790146102d25780638da5cb5b146102fe5780638f32d59b1461032257806395d89b411461032a57610121565b80632ff2e9dc116100f45780632ff2e9dc14610233578063313ce5671461023b578063395093511461025957806342966c681461028557806370a08231146102a457610121565b806306fdde0314610126578063095ea7b3146101a357806318160ddd146101e357806323b872dd146101fd575b600080fd5b61012e61040a565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610168578181015183820152602001610150565b50505050905090810190601f1680156101955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101cf600480360360408110156101b957600080fd5b506001600160a01b0381351690602001356104a0565b604080519115158252519081900360200190f35b6101eb6104b6565b60408051918252519081900360200190f35b6101cf6004803603606081101561021357600080fd5b506001600160a01b038135811691602081013590911690604001356104bc565b6101eb610513565b610243610518565b6040805160ff9092168252519081900360200190f35b6101cf6004803603604081101561026f57600080fd5b506001600160a01b038135169060200135610521565b6102a26004803603602081101561029b57600080fd5b503561055d565b005b6101eb600480360360208110156102ba57600080fd5b50356001600160a01b031661056a565b6102a2610585565b6102a2600480360360408110156102e857600080fd5b506001600160a01b0381351690602001356105e6565b6103066105f4565b604080516001600160a01b039092168252519081900360200190f35b6101cf610608565b61012e61061e565b6101cf6004803603604081101561034857600080fd5b506001600160a01b03813516906020013561067f565b6101cf6004803603604081101561037457600080fd5b506001600160a01b0381351690602001356106bb565b6101eb600480360360408110156103a057600080fd5b506001600160a01b03813581169160200135166106c8565b6102a2600480360360408110156103ce57600080fd5b506001600160a01b0381351690602001356106f3565b6102a2600480360360208110156103fa57600080fd5b50356001600160a01b031661070e565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104965780601f1061046b57610100808354040283529160200191610496565b820191906000526020600020905b81548152906001019060200180831161047957829003601f168201915b5050505050905090565b60006104ad338484610728565b50600192915050565b60025490565b60006104c98484846107b0565b6001600160a01b038416600090815260016020908152604080832033808552925290912054610509918691610504908663ffffffff61087b16565b610728565b5060019392505050565b600081565b60055460ff1690565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104ad918590610504908663ffffffff61089016565b61056733826108a9565b50565b6001600160a01b031660009081526020819052604090205490565b61058d610608565b61059657600080fd5b60055460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360058054610100600160a81b0319169055565b6105f08282610950565b5050565b60055461010090046001600160a01b031690565b60055461010090046001600160a01b0316331490565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104965780601f1061046b57610100808354040283529160200191610496565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104ad918590610504908663ffffffff61087b16565b60006104ad3384846107b0565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6106fb610608565b61070457600080fd5b6105f08282610995565b610716610608565b61071f57600080fd5b61056781610a3d565b6001600160a01b03821661073b57600080fd5b6001600160a01b03831661074e57600080fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0382166107c357600080fd5b6001600160a01b0383166000908152602081905260409020546107ec908263ffffffff61087b16565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610821908263ffffffff61089016565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008282111561088a57600080fd5b50900390565b6000828201838110156108a257600080fd5b9392505050565b6001600160a01b0382166108bc57600080fd5b6002546108cf908263ffffffff61087b16565b6002556001600160a01b0382166000908152602081905260409020546108fb908263ffffffff61087b16565b6001600160a01b038316600081815260208181526040808320949094558351858152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35050565b61095a82826108a9565b6001600160a01b0382166000908152600160209081526040808320338085529252909120546105f0918491610504908563ffffffff61087b16565b6001600160a01b0382166109a857600080fd5b6002546109bb908263ffffffff61089016565b6002556001600160a01b0382166000908152602081905260409020546109e7908263ffffffff61089016565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b038116610a5057600080fd5b6005546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0390921661010002610100600160a81b031990921691909117905556fea265627a7a72305820332223d26ddabcb0063e47e2563255a244ad435fb5313e225d08e2c9862bdb6564736f6c63430005090032

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101215760003560e01c8063715018a6116100ad578063a457c2d711610071578063a457c2d714610332578063a9059cbb1461035e578063dd62ed3e1461038a578063f0dda65c146103b8578063f2fde38b146103e457610121565b8063715018a6146102ca57806379cc6790146102d25780638da5cb5b146102fe5780638f32d59b1461032257806395d89b411461032a57610121565b80632ff2e9dc116100f45780632ff2e9dc14610233578063313ce5671461023b578063395093511461025957806342966c681461028557806370a08231146102a457610121565b806306fdde0314610126578063095ea7b3146101a357806318160ddd146101e357806323b872dd146101fd575b600080fd5b61012e61040a565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610168578181015183820152602001610150565b50505050905090810190601f1680156101955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101cf600480360360408110156101b957600080fd5b506001600160a01b0381351690602001356104a0565b604080519115158252519081900360200190f35b6101eb6104b6565b60408051918252519081900360200190f35b6101cf6004803603606081101561021357600080fd5b506001600160a01b038135811691602081013590911690604001356104bc565b6101eb610513565b610243610518565b6040805160ff9092168252519081900360200190f35b6101cf6004803603604081101561026f57600080fd5b506001600160a01b038135169060200135610521565b6102a26004803603602081101561029b57600080fd5b503561055d565b005b6101eb600480360360208110156102ba57600080fd5b50356001600160a01b031661056a565b6102a2610585565b6102a2600480360360408110156102e857600080fd5b506001600160a01b0381351690602001356105e6565b6103066105f4565b604080516001600160a01b039092168252519081900360200190f35b6101cf610608565b61012e61061e565b6101cf6004803603604081101561034857600080fd5b506001600160a01b03813516906020013561067f565b6101cf6004803603604081101561037457600080fd5b506001600160a01b0381351690602001356106bb565b6101eb600480360360408110156103a057600080fd5b506001600160a01b03813581169160200135166106c8565b6102a2600480360360408110156103ce57600080fd5b506001600160a01b0381351690602001356106f3565b6102a2600480360360208110156103fa57600080fd5b50356001600160a01b031661070e565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104965780601f1061046b57610100808354040283529160200191610496565b820191906000526020600020905b81548152906001019060200180831161047957829003601f168201915b5050505050905090565b60006104ad338484610728565b50600192915050565b60025490565b60006104c98484846107b0565b6001600160a01b038416600090815260016020908152604080832033808552925290912054610509918691610504908663ffffffff61087b16565b610728565b5060019392505050565b600081565b60055460ff1690565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104ad918590610504908663ffffffff61089016565b61056733826108a9565b50565b6001600160a01b031660009081526020819052604090205490565b61058d610608565b61059657600080fd5b60055460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360058054610100600160a81b0319169055565b6105f08282610950565b5050565b60055461010090046001600160a01b031690565b60055461010090046001600160a01b0316331490565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104965780601f1061046b57610100808354040283529160200191610496565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104ad918590610504908663ffffffff61087b16565b60006104ad3384846107b0565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6106fb610608565b61070457600080fd5b6105f08282610995565b610716610608565b61071f57600080fd5b61056781610a3d565b6001600160a01b03821661073b57600080fd5b6001600160a01b03831661074e57600080fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0382166107c357600080fd5b6001600160a01b0383166000908152602081905260409020546107ec908263ffffffff61087b16565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610821908263ffffffff61089016565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008282111561088a57600080fd5b50900390565b6000828201838110156108a257600080fd5b9392505050565b6001600160a01b0382166108bc57600080fd5b6002546108cf908263ffffffff61087b16565b6002556001600160a01b0382166000908152602081905260409020546108fb908263ffffffff61087b16565b6001600160a01b038316600081815260208181526040808320949094558351858152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35050565b61095a82826108a9565b6001600160a01b0382166000908152600160209081526040808320338085529252909120546105f0918491610504908563ffffffff61087b16565b6001600160a01b0382166109a857600080fd5b6002546109bb908263ffffffff61089016565b6002556001600160a01b0382166000908152602081905260409020546109e7908263ffffffff61089016565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b038116610a5057600080fd5b6005546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0390921661010002610100600160a81b031990921691909117905556fea265627a7a72305820332223d26ddabcb0063e47e2563255a244ad435fb5313e225d08e2c9862bdb6564736f6c63430005090032

Deployed Bytecode Sourcemap

110:438:16:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;110:438:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;628:81:3;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;628:81:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2723:145:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;2723:145:1;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;924:89;;;:::i;:::-;;;;;;;;;;;;;;;;3331:224;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;3331:224:1;;;;;;;;;;;;;;;;;:::i;177:42:16:-;;;:::i;930:81:3:-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;4058:200:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;4058:200:1;;;;;;;;:::i;295:77:2:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;295:77:2;;:::i;:::-;;1222:104:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1222:104:1;-1:-1:-1;;;;;1222:104:1;;:::i;1347:137:10:-;;;:::i;624:93:2:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;624:93:2;;;;;;;;:::i;659:77:10:-;;;:::i;:::-;;;;-1:-1:-1;;;;;659:77:10;;;;;;;;;;;;;;979:90;;;:::i;771:85:3:-;;;:::i;4766:210:1:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;4766:210:1;;;;;;;;:::i;1950:137::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;1950:137:1;;;;;;;;:::i;1657:129::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;1657:129:1;;;;;;;;;;:::i;428:117:16:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;428:117:16;;;;;;;;:::i;1655:107:10:-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1655:107:10;-1:-1:-1;;;;;1655:107:10;;:::i;628:81:3:-;697:5;690:12;;;;;;;;-1:-1:-1;;690:12:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;665:13;;690:12;;697:5;;690:12;;697:5;690:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;628:81;:::o;2723:145:1:-;2788:4;2804:36;2813:10;2825:7;2834:5;2804:8;:36::i;:::-;-1:-1:-1;2857:4:1;2723:145;;;;:::o;924:89::-;994:12;;924:89;:::o;3331:224::-;3410:4;3426:26;3436:4;3442:2;3446:5;3426:9;:26::i;:::-;-1:-1:-1;;;;;3489:14:1;;;;;;-1:-1:-1;3489:14:1;;;;;;;;3477:10;3489:26;;;;;;;;;3462:65;;3489:14;;:37;;3520:5;3489:30;:37::i;:::-;3462:8;:65::i;:::-;-1:-1:-1;3544:4:1;3331:224;;;;;:::o;177:42:16:-;218:1;177:42;:::o;930:81:3:-;995:9;;;;930:81;:::o;4058:200:1:-;4163:10;4138:4;4184:20;;;:8;:20;;;;;;;;-1:-1:-1;;;;;4184:29:1;;;;;;;;;;4138:4;;4154:76;;4184:29;;:45;;4218:10;4184:33;:45::i;295:77:2:-;341:24;347:10;359:5;341;:24::i;:::-;295:77;:::o;1222:104:1:-;-1:-1:-1;;;;;1303:16:1;1277:7;1303:16;;;;;;;;;;;;1222:104::o;1347:137:10:-;863:9;:7;:9::i;:::-;855:18;;;;;;1429:6;;1408:40;;1445:1;;1429:6;;;-1:-1:-1;;;;;1429:6:10;;1408:40;;1445:1;;1408:40;1458:6;:19;;-1:-1:-1;;;;;;1458:19:10;;;1347:137::o;624:93:2:-;688:22;698:4;704:5;688:9;:22::i;:::-;624:93;;:::o;659:77:10:-;723:6;;;;;-1:-1:-1;;;;;723:6:10;;659:77::o;979:90::-;1056:6;;;;;-1:-1:-1;;;;;1056:6:10;1042:10;:20;;979:90::o;771:85:3:-;842:7;835:14;;;;;;;;-1:-1:-1;;835:14:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;810:13;;835:14;;842:7;;835:14;;842:7;835:14;;;;;;;;;;;;;;;;;;;;;;;;4766:210:1;4876:10;4851:4;4897:20;;;:8;:20;;;;;;;;-1:-1:-1;;;;;4897:29:1;;;;;;;;;;4851:4;;4867:81;;4897:29;;:50;;4931:15;4897:33;:50::i;1950:137::-;2011:4;2027:32;2037:10;2049:2;2053:5;2027:9;:32::i;1657:129::-;-1:-1:-1;;;;;1755:15:1;;;1729:7;1755:15;;;-1:-1:-1;1755:15:1;;;;;;;;:24;;;;;;;;;;;;;1657:129::o;428:117:16:-;863:9:10;:7;:9::i;:::-;855:18;;;;;;512:26:16;518:11;531:6;512:5;:26::i;1655:107:10:-;863:9;:7;:9::i;:::-;855:18;;;;;;1727:28;1746:8;1727:18;:28::i;6806:248:1:-;-1:-1:-1;;;;;6898:21:1;;6890:30;;;;;;-1:-1:-1;;;;;6938:19:1;;6930:28;;;;;;-1:-1:-1;;;;;6969:15:1;;;;;;;-1:-1:-1;6969:15:1;;;;;;;;:24;;;;;;;;;;;;;:32;;;7016:31;;;;;;;;;;;;;;;;;6806:248;;;:::o;5190:256::-;-1:-1:-1;;;;;5277:16:1;;5269:25;;;;;;-1:-1:-1;;;;;5323:15:1;;:9;:15;;;;;;;;;;;:26;;5343:5;5323:19;:26::i;:::-;-1:-1:-1;;;;;5305:15:1;;;:9;:15;;;;;;;;;;;:44;;;;5375:13;;;;;;;:24;;5393:5;5375:17;:24::i;:::-;-1:-1:-1;;;;;5359:13:1;;;:9;:13;;;;;;;;;;;;:40;;;;5414:25;;;;;;;5359:13;;5414:25;;;;;;;;;;;;;5190:256;;;:::o;1205:145:15:-;1263:7;1295:1;1290;:6;;1282:15;;;;;;-1:-1:-1;1319:5:15;;;1205:145::o;1431:::-;1489:7;1520:5;;;1543:6;;;;1535:15;;;;;;1568:1;1431:145;-1:-1:-1;;;1431:145:15:o;6278:263:1:-;-1:-1:-1;;;;;6352:21:1;;6344:30;;;;;;6400:12;;:23;;6417:5;6400:23;:16;:23;:::i;:::-;6385:12;:38;-1:-1:-1;;;;;6454:18:1;;:9;:18;;;;;;;;;;;:29;;6477:5;6454:22;:29::i;:::-;-1:-1:-1;;;;;6433:18:1;;:9;:18;;;;;;;;;;;:50;;;;6498:36;;;;;;;6433:9;;6498:36;;;;;;;;;;;6278:263;;:::o;7443:179::-;7513:21;7519:7;7528:5;7513;:21::i;:::-;-1:-1:-1;;;;;7574:17:1;;;;;;-1:-1:-1;7574:17:1;;;;;;;;7562:10;7574:29;;;;;;;;;7544:71;;7574:17;;:40;;7608:5;7574:33;:40::i;5789:263::-;-1:-1:-1;;;;;5863:21:1;;5855:30;;;;;;5911:12;;:23;;5928:5;5911:23;:16;:23;:::i;:::-;5896:12;:38;-1:-1:-1;;;;;5965:18:1;;:9;:18;;;;;;;;;;;:29;;5988:5;5965:22;:29::i;:::-;-1:-1:-1;;;;;5944:18:1;;:9;:18;;;;;;;;;;;:50;;;;6009:36;;;;;;;5944:18;;:9;;6009:36;;;;;;;;;;5789:263;;:::o;1906:183:10:-;-1:-1:-1;;;;;1979:22:10;;1971:31;;;;;;2038:6;;2017:38;;-1:-1:-1;;;;;2017:38:10;;;;2038:6;;;;;2017:38;;;;;2065:6;:17;;-1:-1:-1;;;;;2065:17:10;;;;;;-1:-1:-1;;;;;;2065:17:10;;;;;;;;;1906:183::o

Swarm Source

bzzr://332223d26ddabcb0063e47e2563255a244ad435fb5313e225d08e2c9862bdb65
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.